title: 基于SpringBoot+Redis的Session共享与单点登录

date: 2019-07-23 02:55:52

categories:

  • 架构

    author: mrzhou

    tags:
  • SpringBoot
  • redis
  • session
  • 单点登录

基于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实现单点登录的正确打开方式。

基于SpringBoot+Redis的Session共享与单点登录的更多相关文章

  1. springboot+redis实现session共享

    1.场景描述 因项目访问压力有点大,需要做负载均衡,但是登录使用的是公司统一提供的单点登录系统,需要做session共享,否则假如在A机器登录成功,在B机器上操作就会存在用户未登录情况. 2. 解决方 ...

  2. 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享

    因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXi ...

  3. Tomcat7基于Redis的Session共享实战二

    目前,为了使web能适应大规模的访问,需要实现应用的集群部署.集群最有效的方案就是负载均衡,而实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这样我们首先要解决session的统一来保证无 ...

  4. 单点登录实现(spring session+redis完成session共享)

    一.前言 项目中用到的SSO,使用开源框架cas做的.简单的了解了一下cas,并学习了一下 单点登录的原理,有兴趣的同学也可以学习一下,写个demo玩一玩. 二.工程结构 我模拟了 sso的客户端和s ...

  5. [转]Tomcat7基于Redis的Session共享

    转自:http://blog.csdn.net/catoop/article/details/48603891 目前,为了使web能适应大规模的访问,需要实现应用的集群部署.集群最有效的方案就是负载均 ...

  6. Nginx集群配置与redis的session共享策略

    一.什么是Nginx? Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Ramb ...

  7. Spring Boot从入门到精通(七)集成Redis实现Session共享

    单点登录(SSO)是指在多个应用系统中,登录用户只需要登录验证一次就可以访问所有相互信任的应用系统,Redis Session共享是实现单点登录的一种方式.本文是通过Spring Boot框架集成Re ...

  8. nginx反向代理做负载均衡以及使用redis实现session共享配置详解

    1.为什么要用nginx做负载均衡? 首先我们要知道用单机tomcat做的网站,比较理想的状态下能够承受的并发访问在150到200, 按照并发访问量占总用户数的5%到10%技术,单点tomcat的用户 ...

  9. 分布式中使用Redis实现Session共享(二)

    上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最常见的session开始,刚好也重新学习一遍session的实现原理.在阅读之前假设你已经会使用nginx+i ...

随机推荐

  1. HTTP.SYS 详解 (网络转载)

    http.sys 是一个位于Win2003和WinXP SP2中的操作系统核心组件, 能够让任何应用程序通过它提供的接口,以http协议进行信息通讯. 温馨提示:如果用户不慎删除了该驱动文件,不用担心 ...

  2. 孟岩:技术路线的选择重要但不具有决定性(什么是核心竞争力?是你独特的个性知识经验组合,正确的态度应该是着重于你要干的事情,然后认真把这件事情做好,然后融会贯通)good

    转自 http://blog.csdn.net/myan/article/details/3247071   孟岩 2008 年的文章,现在看来还是挺有启发, 送给大家,也送给自己. 最近微软在技术上 ...

  3. 【算法随记三】小半径中值模糊的急速实现(16MB图7.5ms实现) + Photoshop中蒙尘和划痕算法解读。

    在本人的博客里,分享了有关中值模糊的O(1)算法,详见:任意半径中值滤波(扩展至百分比滤波器)O(1)时间复杂度算法的原理.实现及效果 ,这里的算法的执行时间和参数是无关的.整体来说,虽然速度也很快, ...

  4. MakerDAO 代币解释:DAI, WETH, PETH, SIN, MKR(一)

    Maker DAO Token Maker DAO 系统是由多个智能合约 ( Sai Tap, Sai Tub, Vox, Medianiser, etc.), 和 ERC-20 代币组成. 他们一起 ...

  5. 第一个SpringBoot测试实例

    1.SpringBoot项目构建:http://start-spring.io   自动化构建SpringBoot项目,保存在本地并解压 2.安装gradle并配置gradle环境 3.配置阿里云ma ...

  6. git实战经验(很实用)

    推荐学习git很好的网站https://www.breakyizhan.com/git/216.html 以下内容,虽然编排不行,但是请认真的读下去,都是自己平时请自操作的,放心使用. 这是个人的gi ...

  7. [转]Android的taskAffinity

    Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系.我们知道,一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Tas ...

  8. java基础(1)-几种获取类的扩展方式

    摘要 在日常开发过程中经常需要获取类的扩展集.即获取类的子类集(抽象类),或者接口实现类.比如说状态模式中,状态构建类,策略模式中的,策略构造方式.本文介绍几种获取方式. 实现 以策略模式为例 定义了 ...

  9. 牛客假日团队赛1 B

    B.便便传送门(一) 题目链接:https://ac.nowcoder.com/acm/contest/918/B 题目 Farmer John最讨厌的农活是运输牛粪.为了精简这个过程,他制造了一个伟 ...

  10. 33 | 无实例无真相:基于LoadRunner实现企业级服务器端性能测试的实践(下)