deerflow-code/offline-backend-20260512/backend/app/gateway/auth/token_source.py
2026-09-07 18:24:55 +08:00

31 lines
1.1 KiB
Python

"""Resolve the credential that represents the calling browser context.
Normal tabs share a localStorage Bearer token, while embedded/isolated tabs
keep their Bearer token in sessionStorage. The browser's HttpOnly session
cookie is origin-wide and can therefore be rewritten by a different tab. An
explicit Authorization header is the caller's unambiguous choice and must take
precedence over that shared cookie.
"""
from __future__ import annotations
from collections.abc import Mapping
from typing import Protocol
class _TokenRequest(Protocol):
headers: Mapping[str, str]
cookies: Mapping[str, str]
def get_explicit_or_session_token(request: _TokenRequest) -> str | None:
"""Return Bearer header token first, then the shared session cookie."""
authorization = str(request.headers.get("authorization", "") or "").strip()
if authorization:
scheme, _, token = authorization.partition(" ")
if scheme.lower() == "bearer" and token.strip():
return token.strip()
cookie_token = str(request.cookies.get("access_token", "") or "").strip()
return cookie_token or None