基于SpringBoot+Redis的Session共享与单点登录详解

 更新时间:2019年07月23日 08:23:16   作者:蜜友工作室  
这篇文章主要介绍了基于SpringBoot+Redis的Session共享与单点登录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言

使用Redis来实现Session共享,其实网上已经有很多例子了,这是确保在集群部署中最典型的redis使用场景。在SpringBoot项目中,其实可以一行运行代码都不用写,只需要简单添加添加依赖和一行注解就可以实现(当然配置信息还是需要的)。

然后简单地把该项目部署到不同的tomcat下,比如不同的端口(A、B),但项目访问路径是相同的。此时在A中使用set方法,然后在B中使用get方法,就可以发现B中可以获取A中设置的内容。

但如果就把这样的一个项目在多个tomcat中的部署说实现了单点登录,那就不对了。

所谓单点登录是指在不同的项目中,只需要任何一个项目登录了,其他项目不需要登录。

同样是上面的例子,我们把set和get两个方法分别放到两个项目(set、get)中,并且以集群方式把两个项目都部署到服务器A和B中,然后分别访问A服务器的set和B服务器的get,你就会发现完全得不到你想要的结果。

同一项目中的set/get

依赖添加就不说了,直接使用最简单的方式

@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class SessionShareApplication {

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

 @Autowired
 HttpSession session;
 @Autowired
 HttpServletRequest req;
 
 @GetMapping("/set")
 public Object set() {
  session.setAttribute("state", "state was setted.");
  Map<String, Object> map = new TreeMap<>();
  map.put("msg", session.getAttribute("state"));
  map.put("serverPort", req.getLocalPort());
  return map;
 }
 @GetMapping("/get")
 public Object get() {
  Map<String, Object> map = new TreeMap<>();
  map.put("msg", session.getAttribute("state"));
  map.put("serverPort", req.getLocalPort());
  return map;
 }
}

将该项目打war包,分别部署在tomcatA(端口8080),tomcatB(端口8081),然后通过tomcatA/set 方法设置session,再使用 tomcatB/get 方法即可获得session的值。但这只是实现了同一项目session的共享。并不是单点登录。

为了验证,我们不仿将set/get方法拆分为两个项目。

拆分set/get为两个项目

get项目

@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class SetApplication {

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

 @Autowired
 HttpSession session;
 @Autowired
 HttpServletRequest req;
 
 @GetMapping("/")
 public Object set() {
  session.setAttribute("state", "state was setted.");
  Map<String, Object> map = new TreeMap<>();
  map.put("msg", session.getAttribute("state"));
  map.put("serverPort", req.getLocalPort());
  return map;
 }
}

将该项目打包为set.war

set项目

@SpringBootApplication
@EnableRedisHttpSession
@RestController
public class GetApplication {

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

 @Autowired
 HttpSession session;
 @Autowired
 HttpServletRequest req;
 
 @GetMapping("/")
 public Object get() {
  Map<String, Object> map = new TreeMap<>();
  map.put("msg", session.getAttribute("state"));
  map.put("serverPort", req.getLocalPort());
  return map;
 }
}

将该项目打包为get.war

再分别将set.war,get.war部署在tomcatA和tomcatB,再通过 tomcatA/set 设置session内容, 然后通过 tomcatB/get 就发现无法获得session的值。

问题分析

尽管我们使用的路径都是一样的,但其实是两个项目,与前面的一个项目是完全不同的,问题就在于 session和cookie在默认情况下是与项目路径相关的,在同一个项目的情况下两个方法所需要的cookie依赖的项目路径是相同的,所以获取session的值就没有问题,但在后一种情况下,cookie的路径是分别属于不同的项目的,所以第二个项目就无法获得第一个项目中设置的session内容了。

解决方法

解决方法在springboot项目中其实也非常简单。既然cookie路径发生了变化,那我们让它配置为相同的路径就解决了。
在每个子项目中都添加一个配置类或者直接设置cookie的路径,如果有域名还可以设置域名的限制,比如 set.xxx.com 与 get.xxx.com 这种情况与我们就需要设置cookie的域名为 xxx.com,以确保无法在哪个项目下都能够获取 xxx.com 这个域名下的cookie值。这样就确保能够正常获得共享的session值了。

@Configuration
public class CookieConfig {

 @Bean
 public static DefaultCookieSerializer defaultCookieSerializer() {
  DefaultCookieSerializer serializer = new DefaultCookieSerializer();
  serializer.setCookiePath("/");
  //serializer.setDomainName("xxx.com"); //如果使用域名访问,建议对这一句进行设置 
  return serializer;
 }
}

以上才是正直的redis实现单点登录的正确打开方式。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 将Sublime Text 2配置为Java的IDE的教程

    将Sublime Text 2配置为Java的IDE的教程

    这篇文章主要介绍了将Sublime Text 2配置为Java的IDE的教程,包括能让Sublime这个文本编辑器编译和运行Java程序等,需要的朋友可以参考下
    2015-07-07
  • JDBC使用Statement修改数据库

    JDBC使用Statement修改数据库

    这篇文章主要为大家详细介绍了JDBC使用Statement修改数据库,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • 利用Spring Cloud Config结合Bus实现分布式配置中心的步骤

    利用Spring Cloud Config结合Bus实现分布式配置中心的步骤

    这篇文章主要介绍了利用Spring Cloud Config结合Bus实现分布式配置中心的相关资料,文中通过示例代码将实现的步骤一步步介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友下面来一起看看吧
    2018-05-05
  • 基于@MapperScan和@ComponentScan的使用区别

    基于@MapperScan和@ComponentScan的使用区别

    这篇文章主要介绍了@MapperScan和@ComponentScan的使用区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java Elastic-Job分布式定时任务使用方法介绍

    Java Elastic-Job分布式定时任务使用方法介绍

    xxl-job 通过一个中心式的调度平台,调度多个执行器执行任务,调度中心通过 DB 锁保证集群分布式调度的一致性,这样扩展执行器会增大 DB 的压力,然而大部分公司的任务数,执行器并不多;xxl-job 提供了非常好用的监控页面甚至还有任务失败的邮件告警功能
    2023-01-01
  • Java中Boolean和boolean的区别详析

    Java中Boolean和boolean的区别详析

    boolean是基本数据类型Boolean是它的封装类,和其他类一样,有属性有方法,可以new,下面这篇文章主要给大家介绍了关于Java中Boolean和boolean区别的相关资料,需要的朋友可以参考下
    2022-07-07
  • 深入理解hibernate的三种状态

    深入理解hibernate的三种状态

    本篇文章主要介绍了深入理解hibernate的三种状态 ,主要包括了transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),有兴趣的同学可以了解一下
    2017-05-05
  • Java 异常详解

    Java 异常详解

    本文主要介绍了异常与错误的区别,异常的体现分类,异常的处理机制,如何自定义异常等,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • SSM+微信小程序实现物业管理系统及实例代码

    SSM+微信小程序实现物业管理系统及实例代码

    这篇文章主要介绍了SSM+微信小程序实现物业管理系统,ssm微信小程序物业管理系统,有网站后台管理系统,本文通过实例代码给大家展示系统的功能,需要的朋友可以参考下
    2022-02-02
  • 教你如何在Intellij IDEA中集成Gitlab

    教你如何在Intellij IDEA中集成Gitlab

    今天来简单说下,如何在IDEA中集成gitlab项目,默认情况下IDEA中的 VCS => Checkout From Version Control 选项中是没有gitlab这一项的,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧
    2023-10-10

最新评论