Spring Boot 基于 Cookie 实现单点登录:原理、实践与优化详解

前言

在多系统交互的应用场景中,单点登录(SSO)能够显著提升用户体验,减少重复登录的繁琐操作。基于 Cookie 的单点登录方案,凭借其简单直观、浏览器原生支持的特性,成为快速实现单点登录的有效方式。本文将深入探讨 Spring Boot 中基于 Cookie 实现单点登录的原理、具体实现步骤、注意事项,并提供完整代码示例。


一、基于 Cookie 实现单点登录原理

1.1 基本概念

Cookie 是由服务器发送到用户浏览器并存储在本地的小型数据,可在后续的 HTTP 请求中被浏览器自动携带发送回服务器。基于 Cookie 的单点登录,核心在于通过在多个相关系统间共享特定的 Cookie,来识别用户的登录状态,从而实现一次登录,多处访问。

1.2 实现流程

  1. 用户登录主系统:用户在主系统(如main.example.com)输入用户名和密码进行登录。
  2. 生成并设置 Cookie:主系统验证用户身份通过后,生成包含用户身份信息(如用户 ID、用户名等)的 Cookie,并设置该 Cookie 的domain属性为顶级域名(如.example.com),这样该 Cookie 就能在所有子域名(如sub1.example.com、sub2.example.com)的系统中共享。
  3. 访问其他子系统:当用户访问同一顶级域名下的其他子系统时,浏览器会自动携带该 Cookie。子系统接收到请求后,从 Cookie 中获取用户身份信息,验证其有效性。
  4. 验证通过:若验证通过,子系统认为用户已登录,允许其访问受保护资源;若验证失败,则引导用户进行登录。

二、Spring Boot 实现基于 Cookie 的单点登录

2.1 项目搭建与依赖添加

创建 Spring Boot 项目,在pom.xml中添加 Web 相关依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

2.2 登录接口实现

创建AuthController类,实现用户登录功能,并在登录成功后设置共享 Cookie:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;@RestController
public class AuthController {// 模拟用户信息存储(实际应用中从数据库查询)private static final String USERNAME = "admin";private static final String PASSWORD = "123456";@PostMapping("/login")public String login(@RequestParam String username, @RequestParam String password, HttpServletResponse response) {if (USERNAME.equals(username) && PASSWORD.equals(password)) {// 创建包含用户信息的CookieCookie cookie = new Cookie("sso_token", username);// 设置Cookie的domain为顶级域名,实现共享cookie.setDomain(".example.com");cookie.setPath("/");cookie.setMaxAge(3600); // 设置Cookie有效期为1小时response.addCookie(cookie);return "登录成功";}return "登录失败";}
}

2.3 受保护资源接口与验证

创建ProtectedResourceController类,模拟受保护资源,并在请求处理前验证 Cookie:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;@RestController
public class ProtectedResourceController {@GetMapping("/protected")public String protectedResource(HttpServletRequest request) {Optional<Cookie> ssoCookie = Arrays.stream(request.getCookies()).filter(cookie -> "sso_token".equals(cookie.getName())).findFirst();if (ssoCookie.isPresent()) {String username = ssoCookie.get().getValue();return "欢迎," + username + "!这是受保护的资源。";}return "请先登录";}
}

2.4 登出功能实现

创建LogoutController类,实现用户登出功能,即删除共享 Cookie:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;@RestController
public class LogoutController {@GetMapping("/logout")public String logout(HttpServletResponse response) {Cookie cookie = new Cookie("sso_token", null);cookie.setDomain(".example.com");cookie.setPath("/");cookie.setMaxAge(0); // 立即失效response.addCookie(cookie);return "登出成功";}
}

三、跨域场景下的 Cookie 共享实现

当系统分布在不同域名下(跨域),直接共享 Cookie 会受到同源策略限制。可通过以下方式解决:

3.1 中间代理服务

在中间搭建一个代理服务(如 Nginx),配置反向代理规则。当子系统接收到请求时,通过代理服务转发请求到主系统进行 Cookie 验证,验证通过后再将结果返回给子系统。

以 Nginx 配置为例:

server {listen 80;server_name sub1.example.com;location / {proxy_pass http://main.example.com;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Cookie $http_cookie; // 传递Cookie}
}

3.2 JSONP 或 CORS

  • JSONP:通过动态创建
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;import java.util.Arrays;@Configuration
public class CorsConfig {@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.setAllowedOrigins(Arrays.asList("http://sub1.example.com", "http://sub2.example.com"));config.setAllowCredentials(true); // 允许携带Cookieconfig.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));config.setAllowedHeaders(Arrays.asList("*"));UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}
}

四、优缺点分析

4.1 优点

  • 实现简单:利用浏览器原生支持的 Cookie 机制,无需复杂的协议和第三方组件,易于理解和实现。
  • 性能较好:Cookie 由浏览器自动携带,服务器处理逻辑相对简单,在同一域名下的系统间切换响应迅速。
  • 兼容性强:几乎所有浏览器都支持 Cookie,适用于各种前端技术栈的应用。

4.2 缺点

  • 安全风险:Cookie 易受 XSS(跨站脚本攻击)和 CSRF(跨站请求伪造)攻击。若 Cookie 泄露,攻击者可能冒充用户身份。
  • 大小限制:浏览器对单个 Cookie 的大小有限制(通常为 4KB 左右),存储的用户信息不能过多。
  • 跨域复杂:跨域场景下实现 Cookie 共享较为复杂,需要额外的配置和处理。

五、安全防护措施

5.1 防止 XSS 攻击

  • 输入验证:对用户输入的数据进行严格验证和过滤,防止恶意脚本注入。
  • HttpOnly 属性:设置 Cookie 的HttpOnly属性为true,禁止 JavaScript 访问 Cookie,降低 XSS 攻击获取 Cookie 的风险。
    Cookie cookie = new Cookie("sso_token", username);
    cookie.setHttpOnly(true);
    

5.2 防止 CSRF 攻击

  • 添加 CSRF 令牌:在表单或 AJAX 请求中添加随机生成的 CSRF 令牌,服务器验证令牌的有效性。
  • SameSite 属性:设置 Cookie 的SameSite属性为Strict或Lax,限制 Cookie 在跨站请求中的发送。
    Cookie cookie = new Cookie("sso_token", username);
    cookie.setSameSite("Strict");
    

总结

通过本文的介绍,我们全面了解了 Spring Boot 基于 Cookie 实现单点登录的原理、实现方式、跨域处理、优缺点及安全防护措施。虽然该方案存在一定的安全风险,但通过合理的配置和防护手段,能在许多场景下高效实现单点登录功能。开发者可根据项目实际需求,灵活运用这些技术,打造安全、便捷的用户认证体系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ModBus协议详解:从基础概念到C#实现RTU与TCP通讯

ModBus协议是莫迪康公司为了让PLC之间进行数据通信而设计出来的协议。它是一种总线协议&#xff0c;是一种一对多&#xff0c;上下级的关系。 它的应用广泛&#xff0c;具有免费开源&#xff0c;操作简单的有点&#xff0c;并且可以兼容串口和网络通讯&#xff0c;兼容也不错。…

PHP数组排序深度解析:sort()、rsort()、asort()、arsort()、ksort()、krsort() 的适用场景与性能对比

在PHP开发中&#xff0c;数组排序是日常操作的核心技能之一。无论是处理用户数据、产品列表&#xff0c;还是分析日志信息&#xff0c;合理的排序方法能显著提升代码的效率和可维护性。PHP提供了多种数组排序函数&#xff08;如 sort()、rsort()、asort() 等&#xff09;&#…

RabittMQ-高级特性2-应用问题

文章目录 前言延迟队列介绍ttl死信队列存在问题延迟队列插件安装延迟插件使用事务消息分发概念介绍限流非公平分发&#xff08;负载均衡&#xff09; 限流负载均衡RabbitMQ应用问题-幂等性保障顺序性保障介绍1顺序性保障介绍2消息积压总结 前言 延迟队列介绍 延迟队列(Delaye…

HOW - 在 Mac 上的 Chrome 浏览器中调试 Windows 场景下的前端页面

文章目录 为什么需要模拟 Windows 环境&#xff1f;一、修改 User-Agent 模拟 Windows 浏览器方法 1&#xff1a;通过 Chrome 开发者工具修改 UA方法 2&#xff1a;使用浏览器插件 二、模拟 Windows 的字体和滚动条样式1. 模拟 Windows 字体2. 强制显示滚动条&#xff08;模拟 …

如何删除豆包本地大模型

由于无法选择大模型的安装位置&#xff0c;因此会占用C盘大量空间&#xff0c;然后又找到不卸载的地方&#xff0c;经排查豆包大模型安装位为&#xff1a;C:\Users\[当前电脑用户]\AppData\Local\Doubao\User Data&#xff0c;只能进行手动卸载。

Linux C语言线程编程入门笔记

目录 开发环境准备 线程基础概念 进程与线程的关系 线程生命周期 创建线程 等待线程结束 线程函数和参数 互斥锁与共享资源保护 总结 开发环境准备 操作系统&#xff1a;以 Linux 为例&#xff08;Ubuntu/CentOS 等主流发行版&#xff09;。请确保系统已安装 GNU C 编…

levelDB的数据查看(非常详细)

起因:.net大作业天气预报程序(WPF)答辩时&#xff0c;老师问怎么维持数据持久性的&#xff0c;启动时加载的数据存在哪里&#xff0c;我明白老师想考的应该是json文件的解析&#xff08;正反&#xff09;&#xff0c;半天没答上来存那个文件了&#xff08;老师默认这个文件是自…

数据分析怎么做?高效的数据分析方法有哪些?

目录 一、数据分析的对象和目的 &#xff08;一&#xff09;数据分析的常见对象 &#xff08;二&#xff09;数据分析的目的 二、数据分析怎么做&#xff1f; &#xff08;一&#xff09;明确问题 &#xff08;二&#xff09;收集数据 &#xff08;三&#xff09;清洗和…

手写 Vue 源码 === 完善依赖追踪与触发更新

目录 依赖收集的完整实现 trackEffects:建立双向依赖关系 触发更新的完整实现 完整的响应式流程 为什么使用 Map 而不是 Set? 总结 在上一篇文章中,我们介绍了 Vue3 响应式系统的基本原理和 activeEffect 的作用。现在,我们将深入探讨完善后的依赖追踪和触发更新机制…

从代码学习深度学习 - 区域卷积神经网络(R-CNN)系列 PyTorch版

文章目录 前言R-CNNFast R-CNN兴趣区域汇聚层 (RoI Pooling)代码示例:兴趣区域汇聚层 (RoI Pooling) 的计算方法Faster R-CNNMask R-CNN双线性插值 (Bilinear Interpolation) 与兴趣区域对齐 (RoI Align)兴趣区域对齐层的输入输出全卷积网络 (FCN) 的作用掩码输出形状总结前言…

18个国内wordpress主题推荐

工厂wordpress中文主题 红蓝色搭配的工厂wordpress中文主题&#xff0c;适合从事生产、加工的工厂官方网站使用。 https://www.jianzhanpress.com/?p8533 Pithy设计师wordpress网站模板 精练简洁的wordpress模板&#xff0c;设计师或设计工作室展示型网站模板。 https://w…

低成本自动化改造技术锚点深度解析

执行摘要 本文旨在深入剖析四项关键的低成本自动化技术&#xff0c;这些技术为工业转型提供了显著的运营和经济效益。文章将提供实用且深入的指导&#xff0c;涵盖老旧设备联网、AGV车队优化、空压机系统智能能耗管控以及此类项目投资回报率&#xff08;ROI&#xff09;的严谨…

Oracle — 数据管理

介绍 Oracle数据库作为全球领先的关系型数据库管理系统&#xff0c;其数据管理能力以高效性、安全性和智能化为核心。系统通过多维度技术实现海量数据的存储与实时处理&#xff0c;支持高并发事务操作与复杂分析查询&#xff0c;满足企业关键业务需求。在安全领域&#xff0c;O…

【PhysUnits】3.3 SI 基础量纲单位(units/base.rs)

一、源码 这段代码定义了一系列基础物理量纲的类型别名&#xff0c;并使用标记 trait Canonical 来表示它们是国际单位制&#xff08;SI&#xff09;中的基本单位。 use crate::Dimension; use typenum::{P1, Z0};/// 标记特质&#xff0c;表示基础量纲单位 pub trait Canoni…

硬件实操技巧记录

本篇自用&#xff0c;防止自己忘记 焊接技巧 一般都是随机电烙铁锡膏组合。 拆电阻时&#xff0c;电烙铁放在电阻上&#xff0c;加锡膏&#xff0c;这个时候熔点会降低&#xff0c;电阻更容易掉下来&#xff0c;用电烙铁带走&#xff1b;焊电阻时&#xff0c;一端点锡膏&…

13.thinkphp的Session和cookie

一&#xff0e;Session 1. 在使用Session之前&#xff0c;需要开启初始化&#xff0c;在中间件文件middleware.php&#xff1b; // Session 初始化 \think\middleware\SessionInit::class 2. TP6.0不支持原生$_SESSION的获取方式&#xff0c;也不支持session_开头的函数&…

TensorFlow中数据集的创建

目录 前言示例示例1示例2示例3示例4 前言 TensorFlow 的 tf.data.Dataset API 提供了一种灵活且高效的方式来加载和预处理数据。它可以轻松处理大规模数据集&#xff0c;并支持多种数据源格式。 所有数据集相关的内容都在tf.data中&#xff0c;from_tensor_slices&#xff1a;…

第十六章,网络型攻击防范技术

网络攻击介绍 网络攻击 --- 指的是入侵或破坏网络上的服务器 ( 主机 ) &#xff0c;盗取服务器的敏感数据或占用网络带宽。 网络攻击分类&#xff1a; 流量型攻击 网络层攻击 应用层攻击 单包攻击 畸形报文攻击 --- 向目标主机发送有缺陷的IP报文&#xff0c;使得目标在…

服务器不备案有影响吗

在当今数字化的时代&#xff0c;服务器成为了众多企业和个人开展业务、展示自我的重要工具。然而&#xff0c;有一个问题常常被忽视&#xff0c;那就是服务器不备案到底有没有影响&#xff1f; 答案是肯定的&#xff01;服务器不备案&#xff0c;影响可不小。据相关数据显示&a…

【LeetCode Solutions】LeetCode 176 ~ 180 题解

CONTENTS LeetCode 176. 第二高的薪水&#xff08;SQL 中等&#xff09;LeetCode 177. 第 N 高的薪水&#xff08;SQL 中等&#xff09;LeetCode 178. 分数排名&#xff08;SQL 中等&#xff09;LeetCode 179. 最大数&#xff08;中等&#xff09;LeetCode 180. 连续出现的数字…