在写token登录的时候,发现cookie中的token到时自动失效,如果此时有人正在操作,非常影响体验,于是增加了一个token快失效时刷新token的功能。下面代码重点就在TokenTool类中的时间判断

1.先写一个tokenTime的工具类

public class TokenTime {/*1小时以内,token有效1-2小时之内,token进行刷新2小时之后,token失效*///cookie和redis中token超过一小时刷新public  static  final int TokenOutTime_hour=1;//cookie浏览器保存token有效期设为2小时public  static  final int cookie_time=60 * 60 * 2;//redis保存token有效期设为2小时public  static  final int redis_time=60 * 60 * 2;}

2.再写一个TokenTool的工具类

public class TokenTool {//生成Tokenpublic String  CreateToken(){LocalDateTime now=LocalDateTime.now();//年月日时分秒毫秒Date date =new Date();String uuid = UUID.randomUUID().toString();String token=uuid+date.getTime();return token;}//判断token时间戳是否需要刷新public boolean tokenOutTime(String OldToken) throws ParseException {//年月日时分秒毫秒Date date =new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");int Oldmax=OldToken.length();long Newtime=date.getTime();long Oldtime = Long.parseLong(OldToken.substring(36, Oldmax));/*给cookie中的时间加上一小时,1小时以内,token有效1-2小时之内,token进行刷新2小时之后,token失效*/Long OldLoseTime= addDate(Oldtime, TokenTime.TokenOutTime_hour);Date NewDate = new Date(Newtime);Date oldDate = new Date(OldLoseTime);String st= simpleDateFormat.format(oldDate);String en= simpleDateFormat.format(NewDate);Date oldTokenTime=simpleDateFormat.parse(st);Date newTokenTime=simpleDateFormat.parse(en);if (oldTokenTime.before(newTokenTime)){System.out.println("token需要刷新");return true;}else{System.out.println("token不需要刷新");return false;}}//给时间戳增加时间public static Long addDate(long time,long hour) throws ParseException {hour = hour*1*60*60*1000; // 要加上的天数转换成毫秒数time+=hour; // 相加得到新的毫秒数return time; // 将毫秒数转换成日期}
}

3.然后写一个登录接口,代码已经假设你从数据库拿到了用户信息保存在变量userinfo中,将token返回给浏览器保存,并将token和userinfo保存在redis中。

@Resourceprivate RedisTemplate redisTemplate;@RequestMapping("/login")public R token(HttpServletRequest request, HttpServletResponse response) {//假设此时已经从数据库获取到用户信息在userinfoTokenTool token =new TokenTool();String cretoken=token.CreateToken();//生成tokenCookie cookie=new Cookie("tokenUser",cretoken);cookie.setMaxAge(TokenTime.cookie_time);//有效期设为2小时//设置路径cookie.setPath("/");//响应回游览器response.addCookie(cookie);RedisCache redis=new RedisCache(redisTemplate);redis.set(cretoken,userinfo,TokenTime.redis_time);//有效期设为2小时return R.ok(userinfo,"登录成功");}

4.新建一个类型,这个是全局线程。当用户信息经过token验证从redis拿出来之后要保存在这个里面,想用的时候从这个里面拿取就行了。

public class UserThreadLocal {private static ThreadLocal<User> userThread =new ThreadLocal<User>();public static void set(User user){userThread.set(user);}public static User get(){return userThread.get();}//防止内存泄漏public static void remove(){userThread.remove();}
}

5.新建一个拦截器,业务逻辑是 获取浏览器token,再从redis获取userinfo,将userinfo保存在UserThreadLocal线程中。

@Configuration
public class LoginInterceptor implements HandlerInterceptor {@Resourceprivate RedisTemplate redisTemplate;@Autowiredprivate static ObjectMapper objectMapper = new ObjectMapper();//在执行COntroller方法之前执行/*** boolean 表示是否放行*   true:放行 用户可以跳转页面*   false:拦截  之后给定重定向路径** 业务逻辑:*   1.判断用户客户端是否有Cookie/token数据*         如果用户没有token则重定向到用户登陆页面*  2.如果用户token中有数据,则从redis缓存中获取数据*    如果redis中数据为null,则重定向到用户登陆页面*  3.如果reids中有数据,则放行请求.*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {String token = "";//获取Cookie数据Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {if("tokenUser".equals(cookie.getName())){token = cookie.getValue();break;}}//判断Cookie是否为nullif(!StringUtils.isEmpty(token)){//检测缓存中是否有该数据RedisCache redis=new RedisCache(redisTemplate);Object userinfo = redis.get(token);TokenTool cretoken =new TokenTool();if(cretoken.tokenOutTime(token)){String  cookiesAndRedisToken=cretoken.CreateToken();Cookie cookie=new Cookie("tokenUser",cookiesAndRedisToken);cookie.setMaxAge(TokenTime.cookie_time);//有效期设为2小时//设置路径cookie.setPath("/");//响应回游览器response.addCookie(cookie);redis.set(cookiesAndRedisToken,userinfo,TokenTime.redis_time);//有效期设为2小时if(!StringUtils.isEmpty(userinfo)){//将userJSON转化为User对象User user= (User) userinfo;UserThreadLocal.set(user);//用户已经登陆 放行请求return true;}}else{if(!StringUtils.isEmpty(userinfo)){//将userJSON转化为User对象User user= (User) userinfo;UserThreadLocal.set(user);//用户已经登陆 放行请求return true;}}}//表示用户没有登陆response.sendRedirect("/login.html");return false;}//执行完业务逻辑后拦截@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// TODO Auto-generated method stub}//返回页面之前拦截@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {//将ThreadLocal数据清空UserThreadLocal.remove();}}

6.新建一个拦截器配置类,设置要访问拦截器的路径,开放登录接口和静态资源接口,其他都配置成要访问拦截器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry){//添加对用户未登录的拦截器,并添加排除项registry.addInterceptor(loginInterceptor).addPathPatterns("/**")//拦截所有.excludePathPatterns("/js/**","/dist/images/**")//排除样式、脚本、图片等资源文件.excludePathPatterns("/login")//排除登录.excludePathPatterns("/","/index");}
}

7.获取用户信息

    @RequestMapping("/getuserinfo")public R getuserinfo() {User user = UserThreadLocal.get();System.out.println(user);return R.ok(user,"获取用户信息成功");}

采用redis+ThreadLocal获取全局的登录用户信息(二)增加token快失效时刷新相关推荐

  1. 采用redis+ThreadLocal获取全局的登录用户信息(一)

    1.首先进行登录操作,代码已经假设你从数据库拿到了用户信息保存在变量userinfo中,将token返回给浏览器保存,并将token和userinfo保存在redis中. @Resourcepriva ...

  2. 使用uc_authcode 获取论坛当前登录用户信息

    目的:使用uc_authcode 获取论坛当前登录用户信息 曲折:看了Discuz官方的ucenter二次开发手册,其中的Example如下: if(!empty($_COOKIE['Example_ ...

  3. Spring MVC 实战:三种方式获取登录用户信息

    前言 Web 项目中,维持用户登录状态的常用方式有三种,分别是 Cookie.Session.Token,不管哪种方案,都需要获取到用户信息供业务层使用. 由于获取用户信息与具体业务无关,因此在普通的 ...

  4. java_后端获取当前登录用户信息

    后端获取当前登录用户信息 开发过程中,发现有很多地方需要获取当前登录的用户信息,比如新增.修改时候要记录创建人和更新人信息,如果每次操作都从数据库中获取用户信息,会增加不必要的开销,同时也增加数据库的 ...

  5. redis保存登录用户信息

    一.什么是redis? Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSIC编写的开源.包含多种数据结构.支持网络.基于内存.可选持久性的键值对存储数据库. 二.Redis的 ...

  6. 若依框架获取和修改当前登录用户信息

    若依框架获取和修改当前登录用户信息 后台修改 前端修改 前言:做一些功能的时候我们肯定得用到当前登陆者信息,所以我就查找了一下若依怎么获取当前登录者信息,用this.$store.state.user ...

  7. wordpress获取当前登录用户信息的方法

    1). get_currentuserinfo(); 此函数将当前登录用户信息赋给全局变量$current_user以及一些单独的用户信息全局变量例如$display_name, $user_emai ...

  8. Spring微服务间登录用户信息共享思路

    微服务之间使用feign的RequestInterceptor拦截器实现请求头传递当前登录用户信息:各线程中使用ThreadLocal存储数据:使用SpringAOP 在Controller类的方法增 ...

  9. linux ftp登录命令_Linux使用pinky命令查询登录用户信息

    请关注本头条号,每天坚持更新原创干货技术文章. 如需学习视频,请在微信搜索公众号"智传网优"直接开始自助视频学习 1. 前言 本文主要讲解如何在Linux系统上使用pinky命令查 ...

最新文章

  1. 【旧文章搬运】Windbg+Vmware驱动调试入门(一)---Windbg的设置
  2. android仿知乎按钮动效,Android仿知乎客户端关注和取消关注的按钮点击特效实现思路详解...
  3. bat射击游戏代码_这张图打开就是3D射击游戏,我是服气的
  4. Android利用RecognizerIntent识别语音并简单实现打电话动作
  5. CJOJ 2171 火车站开饭店(树型动态规划)
  6. 正在启动python的代码补全客户端_Python交互模式下代码自动补全
  7. Open Graphics Library初步_搭建环境_GLUT
  8. bat脚本保存dir结果_MySQL备份脚本,应该这么写
  9. 名企笔试:京东 2016 算法工程师笔试题(登楼梯)
  10. C语言——素数的详解
  11. 有道智云 php,调用有道智云API,自动翻译WORDPRESS标题为英文
  12. 高频量化交易软件主要的功能?
  13. rtx4090和3090性能差距
  14. java+如何画一个扇形_实现一个扇形的几种方法
  15. java if 空指针_java 空指针异常(java.lang.NullPointerException)
  16. 新型红包套路,论推广和运营,灰产们真是一把好手
  17. 电脑是否存在内存泄漏_如何避免内存泄露
  18. Linux 文件隐藏权限
  19. 人脸识别门禁项目总结(STM32部分)
  20. 南加大计算机游戏专业,南加州大学游戏设计项目有哪些课程?

热门文章

  1. 构建机器学习系统步骤
  2. AbstractQueuedSynchronizer的介绍和原理分析
  3. 漫谈 Windows Server 管理工具
  4. Ubuntu与 Fedora之对比
  5. 12-openldap使用AD密码
  6. 区块链学习之区块链思想的诞生(一)
  7. 快速查看Gradle项目的类库依赖情况
  8. 基于springMVC拦截器实现操作日志统计
  9. 细聊分布式ID生成方法
  10. django中,kindeditor存到数据库的html,前台html标签被自动转义的解决办法