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

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

(0)

相关推荐

  • vue+springboot前后端分离实现单点登录跨域问题解决方法

    最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登录咯,至于不知道什么是单点登录的同学,建议去找一下万能的度娘. 刚接到这个需求的时候,老夫心里便不屑的认为:区区登录何足挂齿,但是,开发的过程狠狠的打了我一巴掌(火辣辣的一巴掌)...,所以这次必须得好好记录一下这次教训,以免以后再踩这样的坑. 我面临的第一个问题是跨域,浏览器控制台直接报CORS,

  • 详解springboot配置多个redis连接

    一.springboot nosql 简介 Spring Data提供其他项目,用来帮你使用各种各样的NoSQL技术,包括MongoDB, Neo4J, Elasticsearch, Solr, Redis,Gemfire, Couchbase和Cassandra.Spring Boot为Redis, MongoDB, Elasticsearch, Solr和Gemfire提供自动配置.你可以充分利用其他项目,但你需要自己配置它们. 1.1.Redis Redis是一个缓存,消息中间件及具有丰富

  • springboot整合redis进行数据操作(推荐)

    redis是一种常见的nosql,日常开发中,我们使用它的频率比较高,因为它的多种数据接口,很多场景中我们都可以用到,并且redis对分布式这块做的非常好. springboot整合redis比较简单,并且使用redistemplate可以让我们更加方便的对数据进行操作. 1.添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starte

  • SpringBoot集成Redis的实现示例

    前面一篇文章已经写了如何搭建一个单机版Redis服务, 那么我们应该怎么在现有的系统中集成进来呢? 由于笔者使用的编程语言是Java, 所以本篇文章主要描述SpringBoot如何集成单Redis节点完成数据的增删改查. SpringBoot环境 快速搭建一个SpringBoot工程 进入 https://start.spring.io 网站, 使用该网站初始化一个SpringBoot工程 添加相关依赖 因为使用spring initializer已经帮我们把Redis的依赖建立好了; 但是由于

  • Springboot2.X集成redis集群(Lettuce)连接的方法

    前提:搭建好redis集群环境,搭建方式请看:https://www.jb51.net/article/143749.htm 1. 新建工程,pom.xml文件中添加redis支持 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2

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

    前言 使用Redis来实现Session共享,其实网上已经有很多例子了,这是确保在集群部署中最典型的redis使用场景.在SpringBoot项目中,其实可以一行运行代码都不用写,只需要简单添加添加依赖和一行注解就可以实现(当然配置信息还是需要的). 然后简单地把该项目部署到不同的tomcat下,比如不同的端口(A.B),但项目访问路径是相同的.此时在A中使用set方法,然后在B中使用get方法,就可以发现B中可以获取A中设置的内容. 但如果就把这样的一个项目在多个tomcat中的部署说实现了单

  • Redis实现Session共享与单点登录

    首先,导包. 在pom.xml文件里面加入以下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</g

  • Redis解决Session共享问题的方法详解

    企业项目中,一般都是将项目部署到多台服务器上,用nginx做负载均衡.这样可以减轻单台服务器的压力,不过这样也带来一些问题,例如之前单机部署的话,session存取都是直接了当的,因为请求就只到这一台服务器上,不需要考虑数据共享.接下来分别用8000和8001端口启动同一个项目,做一个简单演示: 测试接口代码: package com.wl.standard.controller; import cn.hutool.core.util.StrUtil; import com.wl.standar

  • SpringBoot集成redis与session实现分布式单点登录

    目录 单点登录 SSO(Single Sign On) 什么是单点登录? 实现方式 开发技术 单点登录实现流程 实现案例 看效果 前言: 由于考虑到cookie的安全性问题,就有了下面这个版本的sso 单点登录 SSO(Single Sign On) 什么是单点登录? 单点登录的英文名叫做:Single Sign On(简称SSO),指在同一帐号平台下的多个应用系统中,用户只需登录一次,即可访问所有相互信任的系统.简而言之,多个系统,统一登陆. 我们可以这样理解,在一个服务模块登录后,其他模块无

  • SpringBoot+SpringSession+Redis实现session共享及唯一登录示例

    最近在学习springboot,session这个点一直困扰了我好久,今天把这些天踩的坑分享出来吧,希望能帮助更多的人. 一.pom.xml配置 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency>

  • IntelliJ IDEA基于SpringBoot如何搭建SSM开发环境的步骤详解

    之前给大家在博文中讲过如何通过eclipse快速搭建SSM开发环境,但相对而言还是有些麻烦的,今天玄武老师给大家介绍下如何使用IntelliJ IDEA基于SpringBoot来更快速地搭建SSM开发环境,相比于传统搭建方式,极少的配置文件和配置信息会让你彻底爱上它. 环境搭建步骤详解 第1步:创建Spring Initializr项目 在IntelliJ IDEA中新建项目,选择Spring Initializr,JDK版本选择自己安装的版本(首次使用可能显示没有,那么就点击New去按照步骤创

  • SpringBoot Redis用注释实现接口限流详解

    目录 1. 准备工作 2. 限流注解 3. 定制 RedisTemplate 4. 开发 Lua 脚本 5. 注解解析 6. 接口测试 7. 全局异常处理 1. 准备工作 首先我们创建一个 Spring Boot 工程,引入 Web 和 Redis 依赖,同时考虑到接口限流一般是通过注解来标记,而注解是通过 AOP 来解析的,所以我们还需要加上 AOP 的依赖,最终的依赖如下: <dependency> <groupId>org.springframework.boot</g

  • spring boot如何基于JWT实现单点登录详解

    前言 最近我们组要给负责的一个管理系统 A 集成另外一个系统 B,为了让用户使用更加便捷,避免多个系统重复登录,希望能够达到这样的效果--用户只需登录一次就能够在这两个系统中进行操作.很明显这就是单点登录(Single Sign-On)达到的效果,正好可以明目张胆的学一波单点登录知识. 本篇主要内容如下: SSO 介绍 SSO 的几种实现方式对比 基于 JWT 的 spring boot 单点登录实战 注意: SSO 这个概念已经出现很久很久了,目前各种平台都有非常成熟的实现,比如OpenSSO

  • Spring Security基于JWT实现SSO单点登录详解

    SSO :同一个帐号在同一个公司不同系统上登陆 使用SpringSecurity实现类似于SSO登陆系统是十分简单的 下面我就搭建一个DEMO 首先来看看目录的结构 其中sso-demo是父工程项目 sso-client .sso-client2分别对应2个资源服务器,sso-server是认证服务器 引入的pom文件 sso-demo <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q

  • 多个SpringBoot项目采用redis实现Session共享功能

    有时我们可能有多个不同的Web应用,可以相互调用,这时如果每个应用都有自己的session,那用户跳转到另一个应用时就又需要登陆一次,这样会带来很不好的体验,因此我们需要在不同的应用中共享session.这里,我们采用redis来实现. 前置说明 由于只用到redis和springboot的整合,所以只能实现一个URL下的不同端口的应用之间的session共享,如果连应用名称都完全不同的两个应用要实现session共享,在这个基础上还需要使用到Nginx,这种方式我暂时还没有试过.(Spring

随机推荐