fix(auth): 401 dal backend svuota la sessione e segnala session_expired (#25)
api_client._handle_response: su 401 pulisce la sessione Flask e marca g.session_expired. Un solo after_request (app.py) trasforma le pagine HTML rimaste in piedi con un errore generico in un redirect al login con flash; le route JSON/AJAX che già inoltrano il dict di api_client (measure.py, statistics.py) ricevono session_expired nel corpo insieme al 401. Backend (riuso della key, bcrypt a tempo costante) resta al lotto A2. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import re
|
||||
from datetime import date
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from flask import Flask, flash, jsonify, redirect, url_for, session, request
|
||||
from flask import Flask, flash, g, jsonify, redirect, url_for, session, request
|
||||
from flask_babel import Babel, gettext as _
|
||||
from flask_wtf.csrf import CSRFError, CSRFProtect
|
||||
from markupsafe import Markup, escape
|
||||
@@ -186,6 +186,23 @@ def create_app() -> Flask:
|
||||
response.headers.setdefault("Referrer-Policy", "strict-origin-when-cross-origin")
|
||||
return response
|
||||
|
||||
@app.after_request
|
||||
def handle_expired_session(response):
|
||||
"""Turn a 401 from the backend into a redirect, for page loads (#25).
|
||||
|
||||
api_client already emptied the session and set ``g.session_expired``
|
||||
on any 401. JSON/AJAX proxy routes already forward the api_client
|
||||
dict (which carries ``session_expired``) as their own body, so a
|
||||
fetch caller has what it needs. What is left is the page views that
|
||||
swallowed the error (flashed something generic and rendered anyway,
|
||||
e.g. an empty recipe list): those get replaced here, in the one
|
||||
place that sees every response, instead of one check per route.
|
||||
"""
|
||||
if getattr(g, "session_expired", False) and not response.is_json:
|
||||
flash(_("Sessione scaduta: effettua nuovamente l'accesso."), "error")
|
||||
return redirect(url_for("auth.login"))
|
||||
return response
|
||||
|
||||
@app.context_processor
|
||||
def inject_globals():
|
||||
"""Inject global variables into all templates."""
|
||||
|
||||
Reference in New Issue
Block a user