Redis实现Session共享与单点登录
首先,导包。
在pom.xml文件里面加入以下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
jar包不做多解释了,看那个artifactId的内容应该能知道干啥的。
然后是yml文件:
spring: redis: database: 0 host: 127.0.0.1 port: 6379 password: jedis.pool.max-idle: 100 jedis.pool.max-wait: -1ms jedis.pool.min-idle: 2 timeout: 2000ms
是的,很精简。
然后是,到你的RedisConfig文件上面,开启redis的session关联注解(其实不用这个注解也是没问题的,后面自己可以去除看看。)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=60) 这边是设置存入redis里面的值的过期时间。
默认不设置的话,是1800秒即30分钟。
@EnableRedisHttpSession
如:
OK,我们开始共享session咯!
在controller文件里面写2个方法吧
@GetMapping("/setSessionValue") public String setredisResult(HttpServletRequest request){ request.getSession().setAttribute(request.getSession().getId(), "---测试数据---"+request.getRequestURL()); System.out.println(request.getSession().getId()); return "set成功,已经存入session域且redis里面也会有值"; } @GetMapping("/getSessionValue") public String redisResult(HttpServletRequest request) { System.out.println(request.getSession().getId()); String value = String.valueOf(request.getSession().getAttribute(request.getSession().getId())); return "取值成功 :"+value; }
先运行第一个, 如下:
控制台打印出sessionid值:
然后再瞟一眼redis数据库,是的,没错,可以看到redis也存储了这个session会话的相关信息。 (TTL是过期时间)
然后访问下第二个接口,可以看到根据sessionid作为Key去session域是能正常获取值的,
好了,redis实现session共享到此其实已经完毕了!
有人可能会有疑问,怎么体现共享了? 这时候,你如果实现负载均衡,开启两个tomcat服务器,不同端口,然后用通过浏览器通过不同端口去访问,你会发现,通过request.getSession().getId()拿出来的sessionid是一样一样的!
那么接下来简单介绍下,使用这个唯一id来实现单点登录
@GetMapping("/userLogin") public String setRedisResult(HttpServletRequest request){ //第一次登录 //1. 取出当期客户端的sessionId String sId=request.getSession().getId(); //2. 查询该sessionId 是否存在于redis boolean exists = redisUtils.exists(sId); if (!exists){ //2.1未登录过,进行用户信息的校验 //如果通过后,写入session域进行共享,即使是负载不同端口,sessionId不会发生变化 request.getSession().setAttribute(sId, "login success"); redisUtils.setWithTime(sId,"login success",1000); return "success login!"; //如果不通过,那么返回登录页面,省略 }else { //2.2 已经登录过,则存入redis中刷新过期时间,再直接返回成功页面 redisUtils.setWithTime(sId,"login success",1000); return " yes,you are allow!"; } } @GetMapping("/userLoginOut") public String userLoginOut(HttpServletRequest request){ String sId=request.getSession().getId(); redisUtils.remove(sId); return "login out!"; }
ps:代码里使用到的工具类RedisUtils 在之前的文章里有
可以看到以上情况其实单纯使用redis配合sesionid共享后就能完成单点登录;
题外补充:
但是以上这种情况是使用上了redis的session共享,保证了sessionId不变,所以每次去出来,在有效时间内都是一样的。
既然都讲到了单点登录吗,那么如果单纯使用redis不使用session共享怎么去实现呢?那就是将第一次登录的sessionId保存在浏览器cookise里,这样每次登录通过cookise去拿出头一次固定不变的sessionid,来判断用户是否有登录过。
这种思路实现方案是:
//登录接口 @GetMapping("/userLogin") public String setRedisResult(HttpServletRequest request, HttpServletResponse response){ //第一次登录 //1. 取出当期客户端的sessionId String sId=request.getSession().getId(); String cookies = getCookies(request); if (cookies==null || cookies.equals("")){ System.out.println("没有登录过,准备进行登录!"); //执行登录逻辑 //写入cookie writeLoginToken(response,sId); //这里设置cookie的过期时间应当与redis设置的时间且与session失效时间保持一致 //写入redis redisUtils.setWithTime(sId,"userInfo",1000); System.out.println("登录成功!"); return "success login!"; }else{ boolean exists = redisUtils.exists(cookies); if (exists){ System.out.println("已经登录过,正常登录!"); return " yes,you are allow!"; }else { return "信息异常不允许登录"; } } }
到此这篇关于Redis实现Session共享与单点登录的文章就介绍到这了,更多相关Redis Session共享与单点登录内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!