采用redis+ThreadLocal获取全局的登录用户信息(二)增加token快失效时刷新
在写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快失效时刷新相关推荐
- 采用redis+ThreadLocal获取全局的登录用户信息(一)
1.首先进行登录操作,代码已经假设你从数据库拿到了用户信息保存在变量userinfo中,将token返回给浏览器保存,并将token和userinfo保存在redis中. @Resourcepriva ...
- 使用uc_authcode 获取论坛当前登录用户信息
目的:使用uc_authcode 获取论坛当前登录用户信息 曲折:看了Discuz官方的ucenter二次开发手册,其中的Example如下: if(!empty($_COOKIE['Example_ ...
- Spring MVC 实战:三种方式获取登录用户信息
前言 Web 项目中,维持用户登录状态的常用方式有三种,分别是 Cookie.Session.Token,不管哪种方案,都需要获取到用户信息供业务层使用. 由于获取用户信息与具体业务无关,因此在普通的 ...
- java_后端获取当前登录用户信息
后端获取当前登录用户信息 开发过程中,发现有很多地方需要获取当前登录的用户信息,比如新增.修改时候要记录创建人和更新人信息,如果每次操作都从数据库中获取用户信息,会增加不必要的开销,同时也增加数据库的 ...
- redis保存登录用户信息
一.什么是redis? Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSIC编写的开源.包含多种数据结构.支持网络.基于内存.可选持久性的键值对存储数据库. 二.Redis的 ...
- 若依框架获取和修改当前登录用户信息
若依框架获取和修改当前登录用户信息 后台修改 前端修改 前言:做一些功能的时候我们肯定得用到当前登陆者信息,所以我就查找了一下若依怎么获取当前登录者信息,用this.$store.state.user ...
- wordpress获取当前登录用户信息的方法
1). get_currentuserinfo(); 此函数将当前登录用户信息赋给全局变量$current_user以及一些单独的用户信息全局变量例如$display_name, $user_emai ...
- Spring微服务间登录用户信息共享思路
微服务之间使用feign的RequestInterceptor拦截器实现请求头传递当前登录用户信息:各线程中使用ThreadLocal存储数据:使用SpringAOP 在Controller类的方法增 ...
- linux ftp登录命令_Linux使用pinky命令查询登录用户信息
请关注本头条号,每天坚持更新原创干货技术文章. 如需学习视频,请在微信搜索公众号"智传网优"直接开始自助视频学习 1. 前言 本文主要讲解如何在Linux系统上使用pinky命令查 ...
最新文章
- 【旧文章搬运】Windbg+Vmware驱动调试入门(一)---Windbg的设置
- android仿知乎按钮动效,Android仿知乎客户端关注和取消关注的按钮点击特效实现思路详解...
- bat射击游戏代码_这张图打开就是3D射击游戏,我是服气的
- Android利用RecognizerIntent识别语音并简单实现打电话动作
- CJOJ 2171 火车站开饭店(树型动态规划)
- 正在启动python的代码补全客户端_Python交互模式下代码自动补全
- Open Graphics Library初步_搭建环境_GLUT
- bat脚本保存dir结果_MySQL备份脚本,应该这么写
- 名企笔试:京东 2016 算法工程师笔试题(登楼梯)
- C语言——素数的详解
- 有道智云 php,调用有道智云API,自动翻译WORDPRESS标题为英文
- 高频量化交易软件主要的功能?
- rtx4090和3090性能差距
- java+如何画一个扇形_实现一个扇形的几种方法
- java if 空指针_java 空指针异常(java.lang.NullPointerException)
- 新型红包套路,论推广和运营,灰产们真是一把好手
- 电脑是否存在内存泄漏_如何避免内存泄露
- Linux 文件隐藏权限
- 人脸识别门禁项目总结(STM32部分)
- 南加大计算机游戏专业,南加州大学游戏设计项目有哪些课程?