From 781cdf77eb1bdd3f975881bba5b9b7815e3220a8 Mon Sep 17 00:00:00 2001 From: JS Ng Date: Thu, 1 Oct 2026 15:32:41 +0800 Subject: [PATCH] fix: make auth logout() best-effort and never fail local logout Revoking the login session remotely could raise (e.g. 404 'No session ID in client' when the client's auth service session cookie was lost across app workers or swept server-side), which turned /logout into a 500 for the whole app. Logout must always succeed locally: clear flask.g and the stored login session id, attempt remote revocation, and log a warning if it fails. --- campus_python/auth/v1/__init__.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/campus_python/auth/v1/__init__.py b/campus_python/auth/v1/__init__.py index 2009681..79ac60e 100644 --- a/campus_python/auth/v1/__init__.py +++ b/campus_python/auth/v1/__init__.py @@ -3,6 +3,7 @@ Campus Auth resource. """ +import logging from typing import Literal import flask @@ -26,6 +27,8 @@ vaults, ) +logger = logging.getLogger(__name__) + class AuthRoot(ResourceRoot): """Campus Auth resource.""" @@ -218,12 +221,28 @@ def _exchange_code_for_token( return campus.model.OAuthToken.from_resource(resp.json()) def logout(self) -> None: - """Logout the current user by revoking their login session.""" - flask.g.pop("user") - flask.g.pop("device") - if self.logins.has_session(): + """Logout the current user by revoking their login session. + + Remote revocation is best-effort: the login session may already be + gone server-side (expired, swept, or the client's auth service + session cookie lost across app workers), but the local session + state is always cleared so the user is signed out locally + regardless of the revocation outcome. + """ + flask.g.pop("user", None) + flask.g.pop("device", None) + if not self.logins.has_session(): + return + try: login_session = self.logins.from_session() self.logins[login_session.id].revoke() + except Exception as err: + logger.warning( + "Login session revocation failed (continuing with local " + "logout): %s", err + ) + if self.logins._session_key in flask.session: + del flask.session[self.logins._session_key] def get_token(self) -> campus.model.OAuthToken: """Convenience method to get access token for a user.