Skip to content

Commit 2b0f5e1

Browse files
authored
fix: add Path to cookie (#9364)
Closes #9363 Scopes the name of the cookie to the path, as well as adds a `Path` attribute to the cookie ## 📋 Pre-Review Checklist <!-- These checks need to be completed before a PR is reviewed --> - [ ] For large changes, or changes that affect the public API: this change was discussed or approved through an issue, on [Discord](https://marimo.io/discord?ref=pr), or the community [discussions](https://github.com/marimo-team/marimo/discussions) (Please provide a link if applicable). - [x] Any AI generated code has been reviewed line-by-line by the human PR author, who stands by it. - [ ] Video or media evidence is provided for any visual changes (optional). <!-- PR is more likely to be merged if evidence is provided for changes made --> ## ✅ Merge Checklist - [x] I have read the [contributor guidelines](https://github.com/marimo-team/marimo/blob/main/CONTRIBUTING.md). - [x] Documentation has been updated where applicable, including docstrings for API changes. - [x] Tests have been added for the changes made.
1 parent b8dde2c commit 2b0f5e1

2 files changed

Lines changed: 42 additions & 4 deletions

File tree

marimo/_server/api/auth.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def set_username(self, username: str) -> None:
167167
class CustomSessionMiddleware(SessionMiddleware):
168168
"""
169169
Wrapper around starlette's SessionMiddleware to:
170-
- customize the session cookie based on the the port
170+
- customize the session cookie based on the port and base URL
171171
- only run in Edit mode
172172
"""
173173

@@ -188,6 +188,7 @@ def __init__(
188188
# we don't have access to the app state
189189

190190
self.original_session_cookie = session_cookie
191+
self.original_path = path
191192

192193
if version.parse(starlette.__version__) >= version.parse("0.32.0"):
193194
# Domain was added in 0.32.0; we currently don't use it.
@@ -223,11 +224,21 @@ async def __call__(
223224

224225
# We key the token cookie by port to avoid conflicts
225226
# with multiple marimo instances running on the same host
227+
cookie_name = self.original_session_cookie
226228
maybe_port = state.maybe_port
227229
if maybe_port is not None:
228-
self.session_cookie = (
229-
f"{self.original_session_cookie}_{maybe_port}"
230-
)
230+
cookie_name = f"{cookie_name}_{maybe_port}"
231+
232+
base_url = getattr(state.state, "base_url", "")
233+
if base_url:
234+
slug = base_url.lstrip("/").replace("/", "_")
235+
if slug:
236+
cookie_name = f"{cookie_name}_{slug}"
237+
self.path = base_url
238+
else:
239+
self.path = self.original_path
240+
241+
self.session_cookie = cookie_name
231242

232243
return await super().__call__(scope, receive, send)
233244

tests/_server/api/test_auth.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ async def test_custom_session_middleware_call(app: Starlette):
4141

4242
await middleware(scope, mock_receive, mock_send)
4343
assert middleware.session_cookie == "session_1234"
44+
assert middleware.path == "/"
4445

4546

4647
async def test_custom_session_middleware_call_with_port():
@@ -52,6 +53,32 @@ async def test_custom_session_middleware_call_with_port():
5253
assert middleware.session_cookie == "session"
5354

5455

56+
def _app_with_base_url(base_url: str) -> Starlette:
57+
app = create_starlette_app(base_url=base_url, enable_auth=True)
58+
get_starlette_server_state_init(base_url=base_url).apply(app.state)
59+
return app
60+
61+
62+
async def test_custom_session_middleware_scopes_cookie_to_base_url():
63+
app = _app_with_base_url("/marimo1")
64+
middleware = CustomSessionMiddleware(app, "secret_key")
65+
scope = create_connection(app).scope
66+
67+
await middleware(scope, mock_receive, mock_send)
68+
assert middleware.session_cookie == "session_1234_marimo1"
69+
assert middleware.path == "/marimo1"
70+
71+
72+
async def test_custom_session_middleware_scopes_cookie_to_nested_base_url():
73+
app = _app_with_base_url("/apps/ml/notebook")
74+
middleware = CustomSessionMiddleware(app, "secret_key")
75+
scope = create_connection(app).scope
76+
77+
await middleware(scope, mock_receive, mock_send)
78+
assert middleware.session_cookie == "session_1234_apps_ml_notebook"
79+
assert middleware.path == "/apps/ml/notebook"
80+
81+
5582
@pytest.fixture
5683
def app() -> Starlette:
5784
app = create_starlette_app(base_url="", enable_auth=True)

0 commit comments

Comments
 (0)