Redirect to login instead of raw 401 JSON on expired session
A page tab left open past COOKIE_MAX_AGE and then reloaded hit
require_user/require_admin raising before the route body ever ran,
so there was nowhere to catch it and show something friendlier - the
browser just rendered {"detail": "Unauthorized"}. A global exception
handler now redirects GET page loads (never /api/* calls, whose JS
callers parse and handle the JSON error themselves, and never
POST/PUT/DELETE, so a failed login or CSRF check still reports its
own error instead of silently bouncing) with a 401/403 back to /.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+18
@@ -17,6 +17,7 @@ from markupsafe import Markup, escape
|
|||||||
from sqlalchemy import delete, select, text, update
|
from sqlalchemy import delete, select, text, update
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from starlette.responses import HTMLResponse as _HR
|
from starlette.responses import HTMLResponse as _HR
|
||||||
|
from starlette.exceptions import HTTPException as _StarletteHTTPException
|
||||||
|
|
||||||
import urllib.request as _urllib_request
|
import urllib.request as _urllib_request
|
||||||
import urllib.parse as _urllib_parse
|
import urllib.parse as _urllib_parse
|
||||||
@@ -888,6 +889,23 @@ async def _process_callback_query(cq: dict):
|
|||||||
app = FastAPI(title="MONT - инфрастуктурный полигон", docs_url=None, redoc_url=None, openapi_url=None)
|
app = FastAPI(title="MONT - инфрастуктурный полигон", docs_url=None, redoc_url=None, openapi_url=None)
|
||||||
|
|
||||||
|
|
||||||
|
@app.exception_handler(_StarletteHTTPException)
|
||||||
|
async def _auth_redirect_handler(request: Request, exc: _StarletteHTTPException):
|
||||||
|
"""A session that expired while a page tab sat open used to surface as
|
||||||
|
a raw {"detail": "Unauthorized"} JSON blob on reload - require_user/
|
||||||
|
require_admin raise before the page route body ever runs, so there was
|
||||||
|
nowhere in those routes to catch it and show something friendlier.
|
||||||
|
Redirect browser page loads (never /api/* calls, whose JS callers parse
|
||||||
|
the JSON body and show their own error) back to the login page instead."""
|
||||||
|
if (
|
||||||
|
exc.status_code in (401, 403)
|
||||||
|
and request.method == "GET"
|
||||||
|
and not request.url.path.startswith("/api/")
|
||||||
|
):
|
||||||
|
return RedirectResponse(url="/", status_code=303)
|
||||||
|
return JSONResponse(status_code=exc.status_code, content={"detail": exc.detail}, headers=exc.headers)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/admin/access-request/{req_id}/decide")
|
@app.get("/admin/access-request/{req_id}/decide")
|
||||||
def access_request_decide_confirm(req_id: str, action: str, token: str, db: Session = Depends(get_db)):
|
def access_request_decide_confirm(req_id: str, action: str, token: str, db: Session = Depends(get_db)):
|
||||||
"""GET only renders a confirmation page - it must never mutate state,
|
"""GET only renders a confirmation page - it must never mutate state,
|
||||||
|
|||||||
Reference in New Issue
Block a user