zoukankan      html  css  js  c++  java
  • redis单点登录,session,cookie

    来自:https://blog.csdn.net/qq_35387940/article/details/84388644

    首先,导包。

    在pom.xml文件里面加入以下:

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-data-redis</artifactId>
    4. </dependency>
    5. <dependency>
    6. <groupId>org.springframework.session</groupId>
    7. <artifactId>spring-session-data-redis</artifactId>
    8. </dependency>

    jar包不做多解释了,看那个artifactId的内容应该能知道干啥的。

    然后是yml文件:

    1. spring:
    2. redis:
    3. database: 0
    4. host: 127.0.0.1
    5. port: 6379
    6. password:
    7. jedis.pool.max-idle: 100
    8. jedis.pool.max-wait: -1ms
    9. jedis.pool.min-idle: 2
    10. timeout: 2000ms

    是的,很精简。

    然后是,到你的RedisConfig文件上面,开启redis的session关联注解(其实不用这个注解也是没问题的,后面自己可以去除看看。)

    @EnableRedisHttpSession(maxInactiveIntervalInSeconds=60) 这边是设置存入redis里面的值的过期时间。

    默认不设置的话,是1800秒即30分钟。

    @EnableRedisHttpSession

    如:

    OK,我们开始共享session咯!

    在controller文件里面写2个方法吧,

    1. @GetMapping("/setSessionValue")
    2. public String setredisResult(HttpServletRequest request){
    3. request.getSession().setAttribute(request.getSession().getId(), "---测试数据---"+request.getRequestURL());
    4. System.out.println(request.getSession().getId());
    5. return "set成功,已经存入session域且redis里面也会有值";
    6. }
    7. @GetMapping("/getSessionValue")
    8. public String redisResult(HttpServletRequest request) {
    9. System.out.println(request.getSession().getId());
    10. String value = String.valueOf(request.getSession().getAttribute(request.getSession().getId()));
    11. return "取值成功 :"+value;
    12. }

    先运行第一个, 如下:

    控制台打印出sessionid值:

    然后再瞟一眼redis数据库,是的,没错,可以看到redis也存储了这个session会话的相关信息。 (TTL是过期时间)

    然后访问下第二个接口,可以看到根据sessionid作为Key去session域是能正常获取值的,

    好了,redis实现session共享到此其实已经完毕了!

    有人可能会有疑问,怎么体现共享了? 这时候,你如果实现负载均衡,开启两个tomcat服务器,不同端口,然后用通过浏览器通过不同端口去访问,你会发现,通过request.getSession().getId()拿出来的sessionid是一样一样的!

    那么接下来简单介绍下,使用这个唯一id来实现单点登录:

    1. @GetMapping("/userLogin")
    2. public String setRedisResult(HttpServletRequest request){
    3. //第一次登录
    4. //1. 取出当期客户端的sessionId
    5. String sId=request.getSession().getId();
    6. //2. 查询该sessionId 是否存在于redis
    7. boolean exists = redisUtils.exists(sId);
    8. if (!exists){
    9. //2.1未登录过,进行用户信息的校验
    10. //如果通过后,写入session域进行共享,即使是负载不同端口,sessionId不会发生变化
    11. request.getSession().setAttribute(sId, "login success");
    12. redisUtils.setWithTime(sId,"login success",1000);
    13. return "success login!";
    14. //如果不通过,那么返回登录页面,省略
    15. }else {
    16. //2.2 已经登录过,则存入redis中刷新过期时间,再直接返回成功页面
    17. redisUtils.setWithTime(sId,"login success",1000);
    18. return " yes,you are allow!";
    19. }
    20. }
    21. @GetMapping("/userLoginOut")
    22. public String userLoginOut(HttpServletRequest request){
    23. String sId=request.getSession().getId();
    24. redisUtils.remove(sId);
    25. return "login out!";
    26. }

    可以看到以上情况其实单纯使用redis配合sesionid共享后就能完成单点登录;

    题外补充:
    但是以上这种情况是使用上了redis的session共享,保证了sessionId不变,所以每次去出来,在有效时间内都是一样的。
    既然都讲到了单点登录吗,那么如果单纯使用redis不使用session共享怎么去实现呢?那就是将第一次登录的sessionId保存在浏览器cookise里,这样每次登录通过cookise去拿出头一次固定不变的sessionid,来判断用户是否有登录过。
    这种思路实现方案是:

    1. //登录接口
    2. @GetMapping("/userLogin")
    3. public String setRedisResult(HttpServletRequest request, HttpServletResponse response){
    4. //第一次登录
    5. //1. 取出当期客户端的sessionId
    6. String sId=request.getSession().getId();
    7. String cookies = getCookies(request);
    8. if (cookies==null || cookies.equals("")){
    9. System.out.println("没有登录过,准备进行登录!");
    10. //执行登录逻辑
    11. //写入cookie
    12. writeLoginToken(response,sId); //这里设置cookie的过期时间应当与redis设置的时间且与session失效时间保持一致
    13. //写入redis
    14. redisUtils.setWithTime(sId,"userInfo",1000);
    15. System.out.println("登录成功!");
    16. return "success login!";
    17. }else{
    18. boolean exists = redisUtils.exists(cookies);
    19. if (exists){
    20. System.out.println("已经登录过,正常登录!");
    21. return " yes,you are allow!";
    22. }else {
    23. return "信息异常不允许登录";
    24. }
    25. }
    26. }
    1. /**
    2. * 获取浏览器存入
    3. * @param request
    4. * @return
    5. */
    6. public String getCookies(HttpServletRequest request){
    7. //HttpServletRequest 装请求信息类
    8. //HttpServletRespionse 装相应信息的类
    9. Cookie[] cookies = request.getCookies();
    10. if(cookies != null){
    11. for(Cookie cookie : cookies){
    12. if(cookie.getName().equals("SESSION_ID")){
    13. return cookie.getValue();
    14. }
    15. }
    16. }
    17. return null;
    18. }
    19. /**
    20. *设置浏览器cookie
    21. * @param response
    22. * @param token
    23. */
    24. public static void writeLoginToken(HttpServletResponse response,String token){
    25. Cookie ck = new Cookie("SESSION_ID",token);
    26. //设置cookie的域
    27. // ck.setDomain("jc.test.com");
    28. // //代表设在根目录
    29. // ck.setPath("/");
    30. //防止脚本读取
    31. ck.setHttpOnly(true);
    32. //单位是秒,设置成-1代表永久,如果cookie不设置maxage的话,cookie就不会写入硬盘,写在内存中,只在当前页面有效
    33. ck.setMaxAge(1000);
    34. response.addCookie(ck);
    35. }

    就到此吧。

  • 相关阅读:
    Linux GCC
    操作系统中的一些数据结构
    《C程序设计》指针部分学习记录-易混点
    操作系统原理与实践-试验2操作系统的引导记录
    输入字符串测试
    实模式和保护模式
    Unity周记: 2020.07.06-07.12
    Unity论坛问答-如何裁剪一个多边形
    Unity论坛问答-如何让Camera.ScreenToWroldPoint在XZ平面上移动
    Unity杂谈-SRP为什么不再使用CG
  • 原文地址:https://www.cnblogs.com/duende99/p/12851288.html
Copyright © 2011-2022 走看看