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.pswp.cn/pingmian/80148.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80148.shtml
英文地址,請注明出處:http://en.pswp.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. 連續出現的數字…