diff --git a/backend/auth.py b/backend/auth.py index 0d25b83..d1c4b4c 100644 --- a/backend/auth.py +++ b/backend/auth.py @@ -76,22 +76,30 @@ def require_auth(x_auth_token: Optional[str] = Header(default=None)): return session -def require_auth_flexible(x_auth_token: Optional[str] = Header(default=None), auth_token: Optional[str] = Query(default=None, alias="token")): +def require_auth_flexible(x_auth_token: Optional[str] = Header(default=None), ssetoken: Optional[str] = Query(default=None)): """ FastAPI dependency - auth via header OR query parameter. - Used for endpoints accessed by tags that can't send headers. - Query parameter is 'token' (via alias) to avoid conflicts with endpoint parameters. + Used for endpoints accessed by tags and SSE connections that can't send headers. + Query parameter is 'ssetoken' to avoid conflicts with endpoint 'token' parameters. Usage: @app.get("/api/photos/{id}") def get_photo(id: str, session: dict = Depends(require_auth_flexible)): ... + Call with: ?ssetoken=XXX or Header: X-Auth-Token: XXX + Raises: HTTPException 401 if not authenticated """ - session = get_session(x_auth_token or auth_token) + import logging + logger = logging.getLogger("uvicorn.error") + logger.info(f"[AUTH_FLEX] header={x_auth_token!r}, query={ssetoken!r}") + + session = get_session(x_auth_token or ssetoken) + logger.info(f"[AUTH_FLEX] session={session!r}") + if not session: raise HTTPException(401, "Nicht eingeloggt") return session diff --git a/backend/routers/prompts.py b/backend/routers/prompts.py index 5571324..c7ced57 100644 --- a/backend/routers/prompts.py +++ b/backend/routers/prompts.py @@ -32,6 +32,11 @@ OPENROUTER_MODEL = os.getenv("OPENROUTER_MODEL", "anthropic/claude-sonnet-4") router = APIRouter(prefix="/api/prompts", tags=["prompts"]) +@router.get("/test-ssetoken") +def test_ssetoken_auth(session: dict = Depends(require_auth_flexible)): + """Test endpoint for SSE token auth debugging""" + return {"status": "ok", "profile_id": session['profile_id']} + # Metadaten-Schlüssel in workflow aggregate_results (nicht als „einziger“ Nutzer-Output) _WORKFLOW_AGG_META_KEYS = frozenset({ "combined_analysis", diff --git a/frontend/src/utils/api.js b/frontend/src/utils/api.js index 5ab3c7a..b680124 100644 --- a/frontend/src/utils/api.js +++ b/frontend/src/utils/api.js @@ -484,8 +484,9 @@ export const api = { // TODO: Security improvement - use session cookie instead of token in URL // For now, send token as query param since EventSource doesn't support custom headers + // Using 'ssetoken' to avoid conflicts with endpoint 'token' parameters const token = getToken() - if (token) params.append('token', token) + if (token) params.append('ssetoken', token) if (modules) { Object.entries(modules).forEach(([k, v]) => params.append(`modules[${k}]`, v))