SpringBoot+Mybatis+PostMan(六):token登陆认证过程三(redis封装与干掉原来session,避免用户重复登陆)
Springboot+Mybatis+redis+postman项目实战总目录*
番外篇:SpringBoot 用户注册时经MD5加密存入数据库
第二篇章:用户角色权限访问控制
SpringBoot+Mybatis+PostMan(七):用户角色权限访问控制入门(数据模拟实现,不带数据库)
SpringBoot+Mybatis+PostMan(八):用户角色权限访问控制一(数据库用户角色表查询组合)
SpringBoot+Mybatis+PostMan(九):用户角色权限访问控制二(加入资源表和资源角色对应表)
SpringBoot+Mybatis+PostMan(十):用户角色权限访问控制三(禁用session、启用token并集成redis)
在上一篇文章(网页链接:https://www.cnblogs.com/yeyuting/p/14293614.html)中,我们学习了在springboot中嵌入redis,现在,我们对redis进行一个封装,同时实现将原有的token值全部干掉,防止重复登陆功能。
一、新建一个工具类JedisUtil,实现redis的打开、清空redis中原有token值、将新生成的token放到redis中,代码逻辑如下:
/** * @author yeyuting * @create 2021/1/19 */ @Component public class JedisUtil { public void tokenToJedis(User user){ Jedis jedis = getResource() ; jedis.set(user.getUserName() , user.getToken()) ; jedis.expire(user.getUserName() , Constants.TOKEN_EXPIRE_TIME) ; //存储对象 jedis.set(user.getToken() , user.getUserName()) ; jedis.expire(user.getToken() , Constants.TOKEN_EXPIRE_TIME) ; Long currentTime =System.currentTimeMillis() ; jedis.set(user.getUserName()+user.getToken() , currentTime.toString()) ; //用完关闭 jedis.close(); System.out.println("redis中token值为:" + jedis.get(user.getUserName())); System.out.println("redis中用户信息值为:" + jedis.get(user.getToken())); } /** *2021/1/19 15:59 * * @param key * * @return : void */ public void delString(String key) { try{ Jedis jedis = getResource(); /*//存入键值对 String jedisKey = jedis.get(key) ; if(jedisKey.equals(null)){ return; }*/ ScanParams scanParams = new ScanParams() ; StringBuilder paramKey = new StringBuilder("*").append(key).append("*") ; scanParams.match(paramKey.toString()) ; scanParams.count(1000) ; ScanResult<String> sr = jedis.scan("0" , scanParams) ; List<String> a = sr.getResult() ; for(String delkey : a){ jedis.del(delkey) ; } }catch (Exception e){ e.printStackTrace(); } } /** *2021/1/19 15:59 * * @param * * @return : redis.clients.jedis.Jedis */ public Jedis getResource(){ return new Jedis("localhost" , 6379) ; } }
二、接下来就是业务层的实现
1. controller层:
@PostMapping("/loginWithRedis") @ResponseBody public Result loginWithRedis(@RequestBody User user){ Result result = userService.loginWithRedis(user) ; return result ; }
2. UserServiceImpl类:
public Result loginWithRedis(User user ){ User user1 = userMapper.selectByName(user.getUserName()) ; if(user1 == null ){ //response.sendRedirect("/login"); return Results.failure("用户不存在,") ; } if(!user1.getPassword().equals(user.getPassword())){ return Results.failure("密码输入错误") ; } //将原有的token值全部干掉,防止重复登陆 Jedis jedis = jedisUtil.getResource(); //存入键值对 String jedisKey = jedis.get(user1.getUserName()) ; if(jedisKey != null){ jedisUtil.delString(user1.getUserName()); } //生成新的token String token = tokenUtil.generateToken(user1) ; user1.setToken(token); //将新生成的token放到redis中 jedisUtil.tokenToJedis(user1); return Results.successWithData(user1) ; }
3. 拦截器进行配置,将loginWithRedis端口释放出来,让我们能顺利进到这个端口里面进行登录操作。
@Configuration public class MVCConfig implements WebMvcConfigurer { @Bean public HandlerInterceptor authenticationInterceptor(){ return new AuthenticationInterceptor(); } /* * 静态资源映射 * */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/static/**") .addResourceLocations("classpath:/static/") ; } @Override public void addInterceptors (InterceptorRegistry registry){ registry.addInterceptor(authenticationInterceptor()) //表示拦截所有请求 .addPathPatterns("/*") //表示取消对特定路径的拦截 .excludePathPatterns("/loginWithRedis") ; //这里一定不要写成/**/*.js的形式,spring boot无法识别 //取消对static目录下静态资源的拦截 // .excludePathPatterns("/static/**") ; } }
4. 数据库表内容如下:
三、这样一来,代码逻辑也写好了,现在来进行前端测试。
1. 首先来看一下redis初始状态, 可以看出现在redis处于初始状态,里面没有缓存内容:
2. postman前端模拟一下传输数据:
send一下,出现结果:
接下来将loginWithRedis端口拦截住,将上面生成的token放入header里面(如下所示),我们再次send同样内容发现界面被刷新:
此时生成了新的token,如下所示:
紧接着去redis可视化工具中查看一下原来的token值还在不在,发现原来的token已经被干掉了,现在生成了新的token 。
这样一来,redis封装和防止用户重复登陆就完成了。
至此,结束。