违背的青春
当使用jwt进行校验用户信息,由于jwt是无状态的,所以最重要的就是解决刷新token带来问题,一个简单的需求就是15天内免登录。当然最简单粗暴的方式是你可以设token有效期为半个月嘛,这确实是一个解决方案,但是对于信息比较重要的还是不要采用这种方案,最好把token的有效期时间设置为短一些使用refresh刷新token就ok。
大概流程如下图
简单解释下:现在我采取的方案是设置token的有效期为两小时,大概流程
用户通过登录,后端会存储这个token到Redis,key设置为userid,value设置为token,有效期设置为15天(如果一周免登陆,那Redis的有效期就要设置为1周)
如果用户在两个小时后请求数据,这个token是失效的,但是我们可以通过这个失效的token获取payload中的用户信息(我把用户id存储到了token的payload中),通过解析token获取用户id,根据这个id去查到Redis这个key值是否存在,如果还在Redis有效期内我们就可以重新签发token返回给前端,前端把之前存储的token替换为现在得,周而复始,
如果时间过了规定的免登录时间那Redis中,token会失效,我们只需要返回失效信息给前端处理就完事了。
关键代码:
@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Resource
private RedisUtil redisUtil;
@Autowired
private UserMapper userMapper;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException {
String authHeader = request.getHeader(jwtTokenUtil.getHeader());
try {
if (authHeader != null && StringUtils.isNotEmpty(authHeader)) {
String username = jwtTokenUtil.getUsernameFromToken(authHeader);
jwtTokenUtil.validateToken(authHeader);//验证令牌
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(authHeader)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
chain.doFilt