-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
Description
When using Spring WebFlux with a base-path configuration, such as /base, the session_id cookie's Path attribute is set to /base/ (with a trailing slash). However, when the browser accesses the path /base (without a trailing slash), the cookie is not sent, as browsers treat /base and /base/ as two different paths when matching cookies.
This results in the following issues:
-
Inconsistent behavior with browser path matching rules
Browsers consider/baseand/base/as distinct paths, but WebFlux defaults to setting the cookiePathto/base/, which causes the cookie not to be sent when accessing/base. -
Inconsistency with Spring MVC behavior
In Spring MVC, thePathfor thesession_idcookie is set to thebase-pathwithout a trailing slash. This allows the cookie to be sent correctly for both/baseand/base/paths. -
Issues with accessing the base path
When thebase-pathis configured, users expect that accessing/basewill send the session cookie. However, due to the trailing slash in the cookie path, the session cookie is not sent unless the path includes the trailing slash, i.e.,/base/.
Phenomenon Description
When the base-path is configured as /base, and session-based login is implemented, if a user is already logged in, accessing /base is treated as an unauthenticated state. This occurs because the browser does not send the session_id cookie to the backend when accessing /base. The reason is that the cookie's scope is set to /base/, and since the path /base does not match the cookie's path, the browser does not send the cookie, causing the backend to create a new session. However, when accessing paths like /base/**, the cookie's path matches, so the session_id cookie is sent correctly, and the backend recognizes the user as logged in.
Steps to Reproduce
- Configure
application.yml:spring: webflux: base-path: /base
- Start the WebFlux application and access
/base. - The browser does not send the
session_idcookie, but when accessing/base/, the cookie is sent.
Problem Analysis
The issue arises in the CookieWebSessionIdResolver when setting the session_id cookie. Specifically, the initCookie method in CookieWebSessionIdResolver adds a trailing slash to the Path attribute of the cookie:
private ResponseCookie.ResponseCookieBuilder initCookie(ServerWebExchange exchange, String id) {
ResponseCookie.ResponseCookieBuilder builder = ResponseCookie.from(this.cookieName, id)
.path(exchange.getRequest().getPath().contextPath().value() + "/") // Trailing slash added here
.maxAge(getCookieMaxAge())
.httpOnly(true)
.secure("https".equalsIgnoreCase(exchange.getRequest().getURI().getScheme()))
.sameSite("Lax");
if (this.initializer != null) {
this.initializer.accept(builder);
}
return builder;
}This causes the cookie path to be /base/ (with a trailing slash), which does not match when the browser accesses /base (without the slash).
Further Explanation
If the issue is addressed by redirecting requests from /base to /base/, this would make the paths match and the cookie would be sent. However, this approach conflicts with the default behavior of PathMatcher in WebFlux, which treats /base and /base/ as distinct paths. Automatically redirecting to /base/ would interfere with normal path matching behavior and could cause issues with routing in other parts of the application.
Expected Behavior
- WebFlux should allow developers to configure whether the cookie
Pathshould include a trailing slash. - Alternatively, WebFlux should behave like Spring MVC and not append a trailing slash to the
base-pathby default, preventing the path matching issue.
If I misunderstood, please correct me 🫡 and I look forward to your response