一、课程介绍
【课程名称】SpringBoot 2.x 实战仿B站高性能后端项目。
【章节】第三章3.41 双令牌实现登录升级
【讲师】HELLOSTAR
二、课程内容
1.单个token验证登录的缺点
单token使用不灵活。单个token设置的过期时间过长或者过短都不合适。
过期时间过短,则用户短时间内没有操作就会提示登录断开,需要重新登录。用户体验不佳。
过期时间过长,则用户token长时间有效,账号长时间登录状态,容易造成泄露,劫持token的情况发生,安全性不够。
2.双token验证机制
双token分别是access-token和refresh-token,登录之后混合使用这两个token进行校验登录状态。其中access-token的有效时间比较短,一般在2小时左右;refresh-token有效时间比较长,一般在数天。access-token如果过期,首先会验证refresh-token是否过期,如果没过期,会刷新access-token的有效时间,如果也过期了,才会提示用户重新登录。
3.双token代码实现
用户成功登录之后返回前端两个token。两个token保存在redis数据库。并且refresh-token也保存在MySQL数据库。
public Map<String, Object> loginForDts(User user) throws Exception{
/*登录校验,省略,,,,,*/
Long userId = dbUser.getId();
//生成双token
String accessToken = TokenUtil.generateToken(userId);
String refreshToken = TokenUtil.generateRefreshToken(userId);
//保存refresh token到数据库
userDao.deleteRefreshTokenByUserId(userId);
userDao.addRefreshToken(refreshToken, userId, new Date());
Map<String, Object> result = new HashMap<>();
result.put("accessToken", accessToken);
result.put("refreshToken", refreshToken);
return result;
}
登录过程中access-token过期,刷新token。首先校验refresh-token是否过期,没有过期,则重置access-token有效时长。
public String refreshAccessToken(String refreshToken) throws Exception {
RefreshTokenDetail refreshTokenDetail = userDao.getRefreshTokenDetail(refreshToken);
if(refreshTokenDetail == null){
throw new ConditionException("555","token过期!");
}
Long userId = refreshTokenDetail.getUserId();
return TokenUtil.generateToken(userId);
}
用户退出系统。删除refresh-token和access-token
public void logout(String refreshToken, Long userId) {
userDao.deleteRefreshToken(refreshToken, userId);
userDao.deleteAccessToken(userId);
}
三、课程收获
双token登录验证在单token的基础上增加一个token凭证,比之使用起来更加灵活,既能保证用户短时间不需要重复登录,提高用户体验。并且长时间有效的refresh-token也不是主要的登录验证码,只是配合access-token刷新使用,安全性也提高了。实现用户无感的token时间延长,并且阻止用户推出之后继续使用token访问网站资源。