我们知道token的失效时间,是在创建时就规定的时间,如果时间一到,用户即使任然在操作,那么也会强制退出,体验非常不好,本文介绍token续期的常见方式之一双token。
目录
- if(token有效){
- if(token没有过期){
- //放行
- }else{
- //token过期,验证refresh
- if(refresh没有过期){
- //续期生成双token,放行
- }else{
- //两个token都过期,拦截
- }
- }
- }else{
- //token无效,拦截
- }
- @PostMapping("/login")
- public Object login(@RequestBody AdminDto adminDto, HttpServletResponse response){
- //登录时验证码判断
- if(!adminDto.getCode().equals(redisTemplate.opsForValue().get(adminDto.getUuid()))) {
- throw new LoginCodeException();
- }
- Admin loginAdmin = adminService.login(adminDto);
- //这里不用判断是因为,在service层已经作出判断并抛出异常了
- //创建token
- String token = JwtUtil.createToken(loginAdmin.getAid().toString(), loginAdmin.getUsername());
- String refresh = JwtUtil.createRefreshToken(loginAdmin.getAid().toString(), loginAdmin.getUsername());
- //token存储请求头
- response.setHeader("token", token);
- response.setHeader("refresh", refresh);
- //前后端分离程序,后端必须暴露响应头,前端才能获取
- // response.setHeader("Access-Control-Expose-Headers", "token, refreshToken");
- //记录Session
- return R.ok(null).setMsg("登录成功").setCode(200);
- }
- @Slf4j
- @Component
- public class LoginInterceptor implements HandlerInterceptor {
-
- @Autowired
- RoleService roleService;
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- if (request.getMethod().equals("OPTIONS")) {
- return true;
- }
- String token = request.getHeader("token");
- String refresh = request.getHeader("refresh");
- if (JwtUtil.validate(token) == true) {
- if (JwtUtil.isExpire(token) == true) {
- return true;
- }else {
- if (JwtUtil.isExpire(refresh) == true) {
- //创建token
- token = JwtUtil.createToken(JwtUtil.getId(token), JwtUtil.getUsername(token));
- refresh = JwtUtil.createRefreshToken(JwtUtil.getId(token), JwtUtil.getUsername(token));
- //token存储请求头
- response.setHeader("token", token);
- response.setHeader("refresh", refresh);
- return true;
- } else {
- ObjectMapper objectMapper = new ObjectMapper();
- String s = objectMapper.writeValueAsString(R.failed("登录失败").setCode(401));
- PrintWriter writer = response.getWriter();
- writer.write(s);
- return false;
- }
- }
- } else {
- ObjectMapper objectMapper = new ObjectMapper();
- String s = objectMapper.writeValueAsString(R.failed("登录失败").setCode(401));
- PrintWriter writer = response.getWriter();
- writer.write(s);
- return false;
- }
- }
- }
还有一种token+redis的方式,思路类似,只不过在创建长token时,是直接存入redis,由redis中取出是否为空,判断此次登录是否续期。