L2: verify auth state with account on each request
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m49s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m49s
When user has artdag_session cookie, periodically (every 30s) check account's /auth/internal/check-device endpoint. If account says the device is no longer active (SSO logout), clear the cookie immediately. Prevents stale sign-in after logging out from another app. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ from pathlib import Path
|
||||
from contextlib import asynccontextmanager
|
||||
from urllib.parse import quote
|
||||
|
||||
import httpx
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import JSONResponse, HTMLResponse, RedirectResponse
|
||||
|
||||
@@ -72,8 +73,43 @@ def create_app() -> FastAPI:
|
||||
):
|
||||
return await call_next(request)
|
||||
|
||||
# Already logged in — pass through
|
||||
# Already logged in — verify account hasn't revoked auth
|
||||
if get_user_from_cookie(request):
|
||||
device_id = getattr(request.state, "device_id", None)
|
||||
if device_id:
|
||||
# Check every 30s whether account still considers this device active
|
||||
check_at = request.cookies.get("auth_check_at")
|
||||
now = time.time()
|
||||
stale = True
|
||||
if check_at:
|
||||
try:
|
||||
stale = (now - float(check_at)) > 30
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if stale and settings.internal_account_url:
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=3) as client:
|
||||
resp = await client.get(
|
||||
f"{settings.internal_account_url.rstrip('/')}"
|
||||
f"/auth/internal/check-device"
|
||||
f"?device_id={device_id}&app=artdag_l2"
|
||||
)
|
||||
if resp.status_code == 200 and not resp.json().get("active"):
|
||||
# Account revoked — clear cookie
|
||||
response = await call_next(request)
|
||||
response.delete_cookie("artdag_session")
|
||||
response.delete_cookie("pnone_at")
|
||||
response.delete_cookie("auth_check_at")
|
||||
return response
|
||||
except Exception:
|
||||
pass
|
||||
# Update check timestamp
|
||||
response = await call_next(request)
|
||||
response.set_cookie(
|
||||
"auth_check_at", str(now), max_age=60,
|
||||
httponly=True, samesite="lax", secure=True,
|
||||
)
|
||||
return response
|
||||
return await call_next(request)
|
||||
|
||||
# Check cooldown — don't re-check within 5 minutes
|
||||
|
||||
Reference in New Issue
Block a user