今日总结
- java随笔录------OAuth2定义,OAuth2的流程,OAuth2的应用,授权过程,JWT令牌的优点,JWT令牌的缺点,双写一致性
- AI随探录------
- 代码随想录------组合问题3
目录
详细内容
java随笔录
OAuth2
定义
OAuth是一种认证协议。OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。
OAuth2的流程
OAyth包含用户、客户端、授权服务器、资源服务器等角色,用户是自愿的拥有者,客户端不存储资源。
A表示 客户端请求资源拥有者授权。
B表示 资源拥有者授权客户端即黑马网站访问自己的用户信息。
C 客户端即黑马网站携带授权码请求认证。
D认证通过颁发令牌。
E表示客户端即黑马网站携带令牌请求资源服务器获取资源。
F表示资源服务器校验令牌通过后提供受保护资源。
OAuth2的应用
- 访问第三方系统的资源
2.外部系统访问资源
3.前端(客户端)访问资源
授权过程

JWT
JSON Web Token(JWT)是一种使用JSON格式传递数据的网络令牌技术,它是一个开放的行业标准(RFC 7519),它定义了一种简洁的、自包含的协议格式,用于在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任,它可以使用HMAC算法或使用RSA的公钥/私钥对来签名,防止内容篡改。使用JWT可以实现无状态认证。如下所示:

JWT由Header(头部),Payload(负载,可以存放信息字段)和签名(防止jwt内容被篡改,对前两部分进行加密)
传统的基于session的方式是有状态认证,用户登录成功将用户的身份信息存储在服务端,这样加大了服务端的存储压力,并且这种方式不适合在分布式系统中应用。
如果是基于令牌技术在分布式系统中实现认证则服务端不用存储session,可以将用户身份信息存储在令牌中,用户认证通过后认证服务颁发令牌给用户,用户将令牌存储在客户端,去访问应用服务时携带令牌去访问,服务端从jwt解析出用户信息。这个过程就是无状态认证。
JWT令牌的优点
1、jwt基于json,非常方便解析。
2、可以在令牌中自定义丰富的内容,易扩展。
3、通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高。
4、资源服务使用JWT可不依赖认证服务即可完成授权。
JWT令牌的缺点
1、JWT令牌较长,占存储空间比较大。
2.、如果没有签名部分,容易被篡改

双写一致性
双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致
读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间
写操作: 延迟双删(只是控制了脏数据的出现,但是延时的时间不好控制)

- 先删除缓存还是先修改数据库
在多线程并发的情况下,先哪个都会出现问题。
2.为什么要删除两次缓存
先删除缓存后修改数据库肯定是有脏数据的,所以等数据库修改之后,再删一次缓存
3.为什么要延时删除
一般情况下,数据库都是 主从模式,是读写分离的,需要延时一会,让主节点同步到从节点
两种方案:
一:一致性要求高的背景下
采用分布式锁(一般最好是读多写少的数据,将该数据放入到缓存)里面的共享锁和排他锁。但是性能不高。
共享锁代码实例:
java
public Item getById(Integer id){
RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(s:"ITEM_READ_WRITE_LOCK");
//读之前加读锁,读锁的作用就是等待该lockkey释放写锁以后再读
RLock readLock = readWriteLock.readLock();
try {
//开锁
readLock.lock();
System.out.println("readLock...");
Item item =(Item) redisTemplate.opsForValue().get("item:"+id);
if(item !=null){
return item;
}
//查询业务数据
item=new Item(id,name:"华为手机",desc:"华为手机",price:5999.00);
//写入缓存
redisTemplate.opsForValue().set("item:"+id,item);
//返回数据
return item;
}finally {
readLock.unlock();
}
}
排他锁代码实例
java
public void updateById(Integer id) {
RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(s:"ITEM_READ_WRITE_LOCK");
//写之前加写锁,写锁加锁成功,读锁只能等待
RLock writeLock = readWriteLock.writeLock();
try {
//开锁
writeLock.lock();
System.out.println("writeLock...");
//更新业务数据
Item item = new Item(id, name:"华为手机",desc:
"华为手机",price:
5299.00);
try {
Thread.sleep(millis:10000);
} catch (InterruptedException e) {
e.printStackTrace();
//删除缓存
redisTemplate.delete(key:"item:" + id);
} finally {
writeLock.unlock();
}
}
}
二:允许延迟一致的背景下
采用异步通知保证数据的最终一致性,但需要保证MQ的可靠性

也可以采用canal的异步通知。当发生了写数据,就会把数据写入到数据库中,如果数据库发生了变化,就会把这个变化记录到BinLog日志文件中,之后canal就会监听Binlog文件,更新到缓存redis。
二进制日志(BINLOG)记录了所有的DDL(数据定义语言)语句和DML(数据操纵语言)语句,但不包括数据查询(SELECT、SHOW)语句。
AI随探录
代码随想录
组合问题3
找出所有相加之和为
n的k个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例 1:
输入: k = 3, n = 7 输出: [[1,2,4]] 解释: 1 + 2 + 4 = 7 没有其他符合的组合了。示例 2:
输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]] 解释: 1 + 2 + 6 = 9 1 + 3 + 5 = 9 2 + 3 + 4 = 9 没有其他符合的组合了。示例 3:
输入: k = 4, n = 1 输出: [] 解释: 不存在有效的组合。 在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。提示:
2 <= k <= 91 <= n <= 60
java
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new LinkedList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
combine(k,n,1);
return result;
}
public void combine(int k,int n,int startindex) {
if(path.size() == k ) {
int sum = path.stream().mapToInt(Integer::intValue).sum();
if(sum == n){
result.add(new ArrayList<>(path));
}
return;
}
for(int i = startindex; i <= 9; i++) {
path.add(i);
combine(k,n,i + 1);
path.removeLast();
}
}
}