springboot+redis+session共享机制分析

1.简介:
springboot+redis+session共享机制分析其实是模拟实现单点登录的一种方式。在日常开发中,不可避免出现一个业务需要在不同的项目上一起运作才能完成,为了避免每个关联项目都要从新登录的问题,就有了单点登录的概念。一般实现单点登录的思路就是将登录状态的标志进行共享,这个标志可以是session,token等充当!我这里就使用session来作为共享标志。
2.该框架的总体思路:
1.将redis作为存放session的容器,多个关联项目都可以从该redis中访问数据
2.不管在那个关联项目中登录过一次,都会将其生成的session存入redis中
3.每个项目对redis的环境配置一样
**大概流程:**将session存入redis,再次登录,会将cookie中的sessionid信息给服务器,服务器中项目会拿着这个sessionid到redis数据库中找这个session,如果没找到,表示没有登录或登录已过期(redis总过期策略是session在超过规定时间,就会以key键删除数据),这里也体现了sessionid的唯一性的重要性!
3.存在缺陷及改进思路:
1.上边的思路存在一些问题,比如每个项目生成session的策略可能会不一样,也有可能出现不同项目间生成了sessionid一样的session的极端情况,改进:将一个项目专用于登录业务,不做其他的东西,将登录成功创建的session存入redis中,其他关联项目模块都从该项目中获取登录的session,也就是拿redis中的登录数据。
我这里这样做的,创建一个springboot项目用于登录,创建一个springboot项目用于获取登录的session信息。
4.具体实现:
前提:先在自己电脑上安装redis数据库并运行
1.创建一个超简单的模拟登录的springboot(账号密码直接不要,直接登)
关键代码:
需要的的依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-test</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

配置文件:

server:
  port: 9999
#  servlet:
#    session:
#      timeout: 60 #1分钟
spring:
  redis:
    host: 192.168.31.7
    port: 6379

在启动类上加一个注解:@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 30)
**注意:**maxInactiveIntervalInSeconds: 设置 Session 失效时间,使用 Redis Session 之后,原 Spring Boot 的 server.session.timeout 属性不再生效(被覆盖了)!。

@SpringBootApplication
//设置redis中session的有效时间30秒
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 30)
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

测试类:


/**
 * 测试登录的接口
 */
@RestController
@RequestMapping("/user")
//@SessionAttributes
public class LoginController {

    @Autowired
    private HttpServletRequest request;
    //模拟首次登录
    @RequestMapping("/login")
    public String login(HttpServletRequest request){
        this.request=request;
        System.out.println(this.request.getSession().getId());
        //将session存入redis
        this.request.getSession().setAttribute("name","66666666");
        System.out.println(  this.request.getSession().getAttribute("name"));
        return "成功";
    }
    //模拟再次登录

    @RequestMapping("/relogin")
    public String relogin(){
                //从redis中拿数据
        System.out.println("以前的sessionid"+request.getSession().getId());
        System.out.println(request.getSession().getAttribute("name"));
        return request.getSession().getAttribute("name")+"";

    }
//    @RequestMapping("/login1")
//    public String login2(@SessionAttribute Session session){
//        System.out.println(session.getTimeout());
//        return "成功";
//    }
//    @RequestMapping("/login3")
//    public String login3(HttpServletRequest request){
//        System.out.println(request.getSession().getId());
//        return "成功";
//    }
//    @RequestMapping("/login4")
//    public String login4(@ModelAttribute Session session){
//        System.out.println(session.getTimeout());
//        return "成功";
//    }
}

使用postman或apipost工具进行模拟登录请求(注意要开启cookie功能,否则,你的每一个请求就缺少sessionid,服务器会一直认为你的请求全是新登录,也就是会一直创建新的session)

在这里插入图片描述
在这里插入图片描述
登录redis的客户端端窗口查看session:

在这里插入图片描述
用于获取登录的session的springboot的依赖和上边一样,只展示配置文件和测试获取登录代码

server:
  port: 9998
#  servlet:
#    session:
#      timeout: 60 #1分钟
spring:
  redis:
    host: 192.168.31.7
    port: 6379

/**
 * 模拟获取登录信息
 */

@RestController
@RequestMapping("/user")
public class LoginController {

    @RequestMapping("/login")
    public String login(HttpSession session){
        System.out.println(session.getAttribute("name"));
        return session.getAttribute("name").toString();
    }
}

在这里插入图片描述
5.总结:
我写的这个只是提供一种实现单点登录的思路,这个依赖是将session过期删除等操作实现了,我们只需要简单的操作就能实现单点登录的效果。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐