11-SpringSecurity:Session共享

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 11-SpringSecurity:Session共享

背景


本系列教程,是作为团队内部的培训资料准备的。主要以实验的方式来体验 SpringSecurity 的各项Feature。


分布式集群架构下的 Session 共享一般有以下几种实现方案:


  • Session 复制


集群中任一服务器上的 Session 发生变化(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点,从而实现 Session 同步。


  • Session 粘滞


利用 Ngnix 负载均衡策略中的 ip_hash 机制,将某个 ip 的所有请求都定向到同一台服务器上,即定向流量分发,这个其实不存在Session共享,仅是实现了用户请求与某个服务的绑定。


  • Session 持久化


将所有的 Session 集中存储,存储到数据库中,保证 Session 的持久化,但是我们知道,随着用户数据量(活跃)的增加,查询数据库开销也随之增加。


  • Session 共享


将所有的 Session 集中存储,可使用分布式缓存方案比如 Redis 来缓存 Session ,实现 Session 共享,查询效率高,同时可以横向扩展。


显然,上述四种方案实际中应用更多的是最后一种:基于分布式缓存(eg: Memcached, Redis)的Session共享,我们今天就演示这种方案。


新建一个 SpringBoot 项目,起名 springboot-security-session ,核心依赖为 Web , SpringSecurity , SpringSessionRedis


  • pom依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
  • 配置文件
server:
  port: 8000
spring:
  redis:
    host: 10.16.1.110
    port: 6379
    pool.max-idle: 8
    pool.min-idle: 0
    pool.max-active: 8
    pool.max-wait: -1
    password:
    timeout: 1000
  • 资源接口


创建资源接口: 登录之后默认跳转 / ,展示当前服务的端口号。

@RestController
public class SessionController {
  @Value("${server.port}")
  Integer port;
  @GetMapping(value = "/")
  public String greeting() {
    return String.valueOf(port);
  }
}


实验0:伪分布式集群Session共享


开启两个服务:


  1. 一个运行在8000端口:http://localhost:8000

  1. 一个运行在9000端口:http://localhost:9000

Note:在Idea中,可通过以下配置可同时运行一个服务的多个实例。

image.png

实验步骤:


  1. 在浏览器中先访问 http://localhost:8000 ,这时要求登录,输入用户名:user,密码在控制台生成;登录成功后显示: 8000


  1. 然后继续在当前浏览器新开一个Tab,访问 http://localhost:9000 ,不出意外,会直接显示(无需再次登录): 9000


  1. 这样,便通过一个依赖 spring-session-data-redis 实现了 Session 共享(就不贴图了);


Note:


  • 由于仍然采用的传统的 Cookie-Session 模式,所以上述实验必须在同一浏览器下进行,在请求时,浏览器会自动带上 Cookie (其中存了SessionID);


  • 实际生产中,通常通过Nginx进行反向代理,仅对外提供一个域名或接口地址,实现集群的负载均衡;


实验1:再次验证Session共享


Controller 中新增两个接口:一个写入键值对,一个读取键值,接口如下:

@RestController
public class SessionController {
  @Value("${server.port}")
  Integer port;
  @GetMapping(value = "/")
  public String greeting() {
    return String.valueOf(port);
  }
  @GetMapping(value = "/session/set")
  public String setSession(HttpSession session) {
    session.setAttribute("key", "value");
    return port + ": Session updated.";
  }
  @GetMapping(value = "/session/get")
  public String getSession(HttpSession session) {
    Object value = session.getAttribute("key");
    return port + ":" + (String) value;
  }
}

实验步骤:


  1. 在浏览器中先访问 http://localhost:8000/session/set ,这时显示: 8000: Session updated.


  1. 然后继续在当前浏览器新开一个Tab,访问 http://localhost:9000/session/get ,不出意外,会显示: 9000:value


  1. 这样,实现了自定义键值对的 Session 共享;


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
打赏
0
0
0
0
8
分享
相关文章
SpringBoot Ajax跨域问题(session共享问题)
ajax 发送post请求至springBoot出现跨域问题 需要在springBoot加上注解 @CrossOrigin 就能解决
73 0
SpringBoot解决跨域访问的问题
本文介绍了跨域访问的概念及其解决方案。同源策略规定浏览器限制不符合协议、Host和端口的请求,导致跨域访问被禁止。为解决此问题,文中提出了三种策略:1) 前端利用HTML标签的特性(如script、iframe)和JSONP、postMessage规避同源策略;2) 通过代理,如nginx或nodejs中间件,使得所有请求看似来自同一源;3) CORS(跨域资源共享),通过设置HTTP响应头允许特定跨域请求。在SpringBoot中,实现CORS有四种方式,包括使用CorsFilter、重写WebMvcConfigurer、CrossOrigin注解以及直接设置响应头。
186 0
SpringSecurity结合JwtToken验证(后端部分)
SpringSecurity结合JwtToken验证(后端部分)
189 0
SpringSecurity结合JwtToken验证(后端部分)
【SpringSecurity6.x】会话管理
【SpringSecurity6.x】会话管理
123 0
spring security 在没实现session共享的集群环境下 防止用户多次登录的 实现思路
spring security 在没实现session共享的集群环境下 防止用户多次登录的 实现思路
281 0
Spring_Session解决Session共享的问题(二十三)下
三.五 配置静态资源,添加过滤器 三.六 配置静态资源 三.七 页面跳转 Controller PageController 三.八 员工的登录和注销 三.九 模拟验证
168 0
Spring_Session解决Session共享的问题(二十三)下
Spring_Session解决Session共享的问题(二十三)上
一. Spring-Session介绍 二. SpringBoot 整合 Spring-Session 使用 三. SpringSession 的详细使用 三.一 pom.xml 添加依赖 三.二 数据库信息 三.三 其他的相关信息 三.四 添加登录和权限拦截的过滤器 LoginInterceptor
1098 0
Spring_Session解决Session共享的问题(二十三)上
springboot+springsecurity session配置管理
在实际的使用过程中,用户会话的有效期以及管理也是很重要的部分。不同需求管理方式也不一样。本文就是根据我在项目中的使用而总结的经验,可能并不全面,但会以最直接的方式展示,也方便快速上手。同时也展示出前后端分离前后的配置,差别仅是路径和拦截而已。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等