-
Notifications
You must be signed in to change notification settings - Fork 38.7k
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/base
and/base/
as distinct paths, but WebFlux defaults to setting the cookiePath
to/base/
, which causes the cookie not to be sent when accessing/base
. -
Inconsistency with Spring MVC behavior
In Spring MVC, thePath
for thesession_id
cookie is set to thebase-path
without a trailing slash. This allows the cookie to be sent correctly for both/base
and/base/
paths. -
Issues with accessing the base path
When thebase-path
is configured, users expect that accessing/base
will 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_id
cookie, 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
Path
should include a trailing slash. - Alternatively, WebFlux should behave like Spring MVC and not append a trailing slash to the
base-path
by default, preventing the path matching issue.
If I misunderstood, please correct me 🫡 and I look forward to your response