diff --git a/starlette/middleware/sessions.py b/starlette/middleware/sessions.py index d1b1d5a0f..a13ec5c0e 100644 --- a/starlette/middleware/sessions.py +++ b/starlette/middleware/sessions.py @@ -49,14 +49,16 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: async def send_wrapper(message: Message) -> None: if message["type"] == "http.response.start": + path = scope.get("root_path", "") or "/" if scope["session"]: # We have session data to persist. data = b64encode(json.dumps(scope["session"]).encode("utf-8")) data = self.signer.sign(data) headers = MutableHeaders(scope=message) - header_value = "%s=%s; path=/; Max-Age=%d; %s" % ( + header_value = "%s=%s; path=%s; Max-Age=%d; %s" % ( self.session_cookie, data.decode("utf-8"), + path, self.max_age, self.security_flags, ) @@ -66,7 +68,7 @@ async def send_wrapper(message: Message) -> None: headers = MutableHeaders(scope=message) header_value = "{}={}; {}".format( self.session_cookie, - "null; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT;", + f"null; path={path}; expires=Thu, 01 Jan 1970 00:00:00 GMT;", self.security_flags, ) headers.append("Set-Cookie", header_value) diff --git a/tests/middleware/test_session.py b/tests/middleware/test_session.py index 3f71232e6..68cf36df9 100644 --- a/tests/middleware/test_session.py +++ b/tests/middleware/test_session.py @@ -101,3 +101,15 @@ def test_secure_session(): response = secure_client.get("/view_session") assert response.json() == {"session": {}} + + +def test_session_cookie_subpath(): + app = create_app() + second_app = create_app() + second_app.add_middleware(SessionMiddleware, secret_key="example") + app.mount("/second_app", second_app) + client = TestClient(app, base_url="http://testserver/second_app") + response = client.post("second_app/update_session", json={"some": "data"}) + cookie = response.headers["set-cookie"] + cookie_path = re.search(r"; path=(\S+);", cookie).groups()[0] + assert cookie_path == "/second_app"