常見配置
本節包含適用於所有或大多數 Spring Session 模組的常見配置。它包含以下用例的配置示例:
更改會話 ID 的生成方式
預設情況下,Spring Session 使用 UuidSessionIdGenerator,它又使用 java.util.UUID 來生成會話 ID。在某些情況下,最好包含其他字元以增加熵,或者您可能希望使用不同的演算法來生成會話 ID。要更改此設定,您可以提供一個自定義的 SessionIdGenerator bean
-
Java
@Bean
public SessionIdGenerator sessionIdGenerator() {
return new MySessionIdGenerator();
}
class MySessionIdGenerator implements SessionIdGenerator {
@Override
public String generate() {
// ...
}
}
在暴露您的 SessionIdGenerator bean 後,Spring Session 將使用它來生成會話 ID。
如果您手動配置 SessionRepository bean(例如,而不是使用 @EnableRedisHttpSession),您可以直接在 SessionRepository 實現上設定 SessionIdGenerator
SessionRepository 實現中設定 SessionIdGenerator-
Java
@Bean
public RedisSessionRepository redisSessionRepository(RedisOperations redisOperations) {
RedisSessionRepository repository = new RedisSessionRepository(redisOperations)
repository.setSessionIdGenerator(new MySessionIdGenerator());
return repository;
}
自定義會話 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 的路徑定製為 /(而不是預設的上下文根)。 |
| 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 的路徑。預設值:上下文根。 -
cookieMaxAge:指定在會話建立時要設定的 Cookie 的最大年齡。預設值:-1,表示當瀏覽器關閉時應刪除 Cookie。 -
jvmRoute:指定一個字尾,該字尾將附加到會話 ID 幷包含在 Cookie 中。用於識別要路由到哪個 JVM 以實現會話親和性。對於某些實現(即 Redis),此選項不提供效能優勢。但是,它可以幫助跟蹤特定使用者的日誌。 -
domainName:允許指定用於 Cookie 的特定域名。此選項易於理解,但通常需要在開發和生產環境之間進行不同的配置。請參閱domainNamePattern作為替代方案。 -
domainNamePattern:一個不區分大小寫的模式,用於從HttpServletRequest#getServerName()中提取域名。該模式應提供一個用於提取 Cookie 域值的分組。如果正則表示式不匹配,則不設定任何域並使用現有域。如果正則表示式匹配,則第一個分組用作域。 -
sameSite:SameSiteCookie 指令的值。要停用SameSiteCookie 指令的序列化,您可以將此值設定為null。預設值:Lax -
rememberMeRequestAttribute:指示記住我登入的請求屬性名稱。如果指定,cookie 將以Integer.MAX_VALUE寫入。
|
如果您正在使用 |
WebFlux 中的自定義 Cookie
您可以透過將 WebSessionIdResolver 作為 Spring bean 暴露來定製 WebFlux 應用程式中會話 cookie 的寫入方式。Spring Session 預設使用 CookieWebSessionIdResolver。以下示例展示瞭如何定製 Spring Session 的 cookie
@Bean
public WebSessionIdResolver webSessionIdResolver() {
CookieWebSessionIdResolver resolver = new CookieWebSessionIdResolver();
resolver.setCookieName("JSESSIONID"); (1)
resolver.addCookieInitializer((builder) -> builder.path("/")); (2)
resolver.addCookieInitializer((builder) -> builder.sameSite("Strict")); (3)
return resolver;
}
| 1 | 我們將 Cookie 的名稱定製為 JSESSIONID。 |
| 2 | 我們將 Cookie 的路徑定製為 /(而不是預設的上下文根)。 |
| 3 | 我們將 SameSite cookie 指令定製為 Strict。 |
提供 ReactiveSessionRegistry 的 Spring Session 實現
Spring Session 與 Spring Security 整合以支援其響應式併發會話控制。這允許限制單個使用者可以同時擁有的活動會話的數量,但與預設的 Spring Security 支援不同,這在叢集環境中也有效。這是透過提供 Spring Security 的 ReactiveSessionRegistry 介面的 SpringSessionBackedReactiveSessionRegistry 實現來完成的。
-
Java
@Bean
public <S extends Session> SpringSessionBackedReactiveSessionRegistry<S> sessionRegistry(
ReactiveSessionRepository<S> sessionRepository,
ReactiveFindByIndexNameSessionRepository<S> indexedSessionRepository) {
return new SpringSessionBackedReactiveSessionRegistry<>(sessionRepository, indexedSessionRepository);
}
請參閱Spring Security 併發會話控制文件以瞭解使用 ReactiveSessionRegistry 的更多方法。您還可以在此處檢視示例應用程式。