Spring Session - 自訂 Cookie

本指南說明如何設定 Spring Session 以搭配 Java 配置使用自訂 Cookie。本指南假設您已在專案中使用您選擇的資料儲存區設定 Spring Session。例如,搭配 Redis 的 HttpSession。

您可以在「自訂 Cookie」範例應用程式中找到完整的指南。

設定 Spring Session 後,您可以透過將 CookieSerializer 公開為 Spring bean,來自訂會話 Cookie 的寫入方式。Spring Session 隨附 DefaultCookieSerializer。當您使用 @EnableRedisHttpSession 之類的配置時,將 DefaultCookieSerializer 公開為 Spring bean 會擴增現有的配置。以下範例示範如何自訂 Spring Session 的 Cookie

	@Bean
	public CookieSerializer cookieSerializer() {
		DefaultCookieSerializer serializer = new DefaultCookieSerializer();
		serializer.setCookieName("JSESSIONID"); (1)
		serializer.setCookiePath("/"); (2)
		serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$"); (3)
		return serializer;
	}
1 我們將 Cookie 的名稱自訂為 JSESSIONID
2 我們將 Cookie 的路徑自訂為 / (而非預設的 context root)。
3 我們將網域名稱模式 (正規表示式) 自訂為 ^.?\\.(\\w\\.[a-z]+)$ 。這允許跨網域和應用程式共用會話。如果正規表示式不符,則不會設定網域,並使用現有的網域。如果正規表示式相符,則第一個群組會用作網域。這表示對 child.example.com 的請求會將網域設定為 example.com。但是,對 localhost:8080/192.168.1.100:8080/ 的請求會讓 Cookie 保持未設定狀態,因此在開發中仍然可以運作,而無需對生產環境進行任何變更。
您應該只比對有效的網域字元,因為網域名稱會反映在回應中。這樣做可以防止惡意使用者執行 HTTP 回應分割等攻擊。

提供以下配置選項

  • cookieName:要使用的 Cookie 名稱。預設值:SESSION

  • useSecureCookie:指定是否應使用安全 Cookie。預設值:在建立時使用 HttpServletRequest.isSecure() 的值。

  • cookiePath:Cookie 的路徑。預設值:Context root。

  • cookieMaxAge:指定在建立會話時要設定的 Cookie 最大期限。預設值:-1,表示在瀏覽器關閉時應移除 Cookie。

  • jvmRoute:指定要附加到會話 ID 並包含在 Cookie 中的後綴。用於識別要路由到哪個 JVM 以實現會話親和性。在某些實作中 (即 Redis),此選項沒有效能優勢。但是,它可以協助追蹤特定使用者的記錄。

  • domainName:允許指定要用於 Cookie 的特定網域名稱。此選項易於理解,但通常需要在開發和生產環境之間進行不同的配置。請參閱 domainNamePattern 作為替代方案。

  • domainNamePattern:用於從 HttpServletRequest#getServerName() 擷取網域名稱的不區分大小寫的模式。此模式應提供單一群組,用於擷取 Cookie 網域的值。如果正規表示式不符,則不會設定網域,並使用現有的網域。如果正規表示式相符,則第一個群組會用作網域。

  • sameSite:SameSite Cookie 指令的值。若要停用 SameSite Cookie 指令的序列化,您可以將此值設定為 null。預設值:Lax

您應該只比對有效的網域字元,因為網域名稱會反映在回應中。這樣做可以防止惡意使用者執行 HTTP 回應分割等攻擊。

本節說明如何使用 custom-cookie 範例應用程式。

您可以透過取得原始碼並叫用以下命令來執行範例

$ ./gradlew :spring-session-sample-javaconfig-custom-cookie:tomcatRun
為了讓範例運作,您必須在本機主機上安裝 Redis 2.8+,並以預設埠 (6379) 執行它。或者,您可以更新 RedisConnectionFactory 以指向 Redis 伺服器。另一個選項是使用 Docker 在本機主機上執行 Redis。請參閱 Docker Redis 儲存庫以取得詳細指示。

您現在應該能夠在 localhost:8080/ 存取應用程式

現在您可以使用應用程式。請填寫具有以下資訊的表單

  • 屬性名稱: username

  • 屬性值: rob

現在按一下「設定屬性」按鈕。您現在應該會在表格中看到顯示的值。

如果您查看應用程式的 Cookie,您可以看到 Cookie 已儲存為自訂名稱 JSESSIONID