diff --git a/starlette/middleware/sessions.py b/starlette/middleware/sessions.py index 3ff1e3de1..597de38a2 100644 --- a/starlette/middleware/sessions.py +++ b/starlette/middleware/sessions.py @@ -17,6 +17,7 @@ def __init__( secret_key: typing.Union[str, Secret], session_cookie: str = "session", max_age: typing.Optional[int] = 14 * 24 * 60 * 60, # 14 days, in seconds + path: str = "/", same_site: str = "lax", https_only: bool = False, ) -> None: @@ -24,6 +25,7 @@ def __init__( self.signer = itsdangerous.TimestampSigner(str(secret_key)) self.session_cookie = session_cookie self.max_age = max_age + self.path = path self.security_flags = "httponly; samesite=" + same_site if https_only: # Secure flag can be used with HTTPS only self.security_flags += "; secure" @@ -49,7 +51,6 @@ 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")) @@ -58,7 +59,7 @@ async def send_wrapper(message: Message) -> None: header_value = "{session_cookie}={data}; path={path}; {max_age}{security_flags}".format( # noqa E501 session_cookie=self.session_cookie, data=data.decode("utf-8"), - path=path, + path=self.path, max_age=f"Max-Age={self.max_age}; " if self.max_age else "", security_flags=self.security_flags, ) @@ -66,10 +67,12 @@ async def send_wrapper(message: Message) -> None: elif not initial_session_was_empty: # The session has been cleared. headers = MutableHeaders(scope=message) - header_value = "{}={}; {}".format( - self.session_cookie, - f"null; path={path}; expires=Thu, 01 Jan 1970 00:00:00 GMT;", - self.security_flags, + header_value = "{session_cookie}={data}; path={path}; {expires}{security_flags}".format( # noqa E501 + session_cookie=self.session_cookie, + data="null", + path=self.path, + expires="expires=Thu, 01 Jan 1970 00:00:00 GMT; ", + security_flags=self.security_flags, ) headers.append("Set-Cookie", header_value) await send(message) diff --git a/tests/middleware/test_session.py b/tests/middleware/test_session.py index 3cb755ed0..a044153a6 100644 --- a/tests/middleware/test_session.py +++ b/tests/middleware/test_session.py @@ -122,7 +122,9 @@ def test_session_cookie_subpath(test_client_factory): routes=[ Route("/update_session", endpoint=update_session, methods=["POST"]), ], - middleware=[Middleware(SessionMiddleware, secret_key="example")], + middleware=[ + Middleware(SessionMiddleware, secret_key="example", path="/second_app") + ], ) app = Starlette(routes=[Mount("/second_app", app=second_app)]) client = test_client_factory(app, base_url="http://testserver/second_app")