49 lines
1.5 KiB
Python
49 lines
1.5 KiB
Python
"""Session token generation and validation."""
|
|
|
|
from typing import Any
|
|
from fastapi import Response
|
|
from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired
|
|
|
|
from app.config import settings
|
|
|
|
def get_serializer() -> URLSafeTimedSerializer:
|
|
"""Return a configured URLSafeTimedSerializer."""
|
|
return URLSafeTimedSerializer(settings.SECRET_KEY)
|
|
|
|
def create_session(response: Response, user_id: int = 1) -> None:
|
|
"""Create a new session token and set it as an HTTP-only cookie."""
|
|
serializer = get_serializer()
|
|
token = serializer.dumps({"user_id": user_id})
|
|
|
|
response.set_cookie(
|
|
key=settings.COOKIE_NAME,
|
|
value=token,
|
|
max_age=settings.COOKIE_MAX_AGE_SECONDS,
|
|
secure=settings.COOKIE_SECURE,
|
|
httponly=True,
|
|
samesite="lax",
|
|
)
|
|
|
|
def clear_session(response: Response) -> None:
|
|
"""Clear the session cookie."""
|
|
response.delete_cookie(
|
|
key=settings.COOKIE_NAME,
|
|
secure=settings.COOKIE_SECURE,
|
|
httponly=True,
|
|
samesite="lax",
|
|
)
|
|
|
|
def verify_session(token: str) -> int | None:
|
|
"""
|
|
Verify the session token.
|
|
Returns the user_id if valid, or None if invalid/expired.
|
|
"""
|
|
serializer = get_serializer()
|
|
try:
|
|
data: dict[str, Any] = serializer.loads(
|
|
token,
|
|
max_age=settings.COOKIE_MAX_AGE_SECONDS
|
|
)
|
|
return data.get("user_id")
|
|
except (BadSignature, SignatureExpired):
|
|
return None
|