Soy un desarrollador web novato, pero un programador experimentado de python y Apache dolt. Recientemente, he estado jugando con el alojamiento de un sitio web pequeño y aprendiendo algunos problemas de alojamiento, Flask, plantillas html, etc.
He seguido varios tutoriales de Flask sobre cómo controlar el acceso a las páginas con decoradores @login_required en puntos finales con control de acceso y usar la session para almacenar un par de kv registrado. Todo esto funciona perfectamente cuando se ejecuta localmente en el servidor de desarrollo de Flask en mi máquina local. Sin embargo, cuando presiono esto en mi servicio de alojamiento, obtengo lo que creo que es un comportamiento almacenado en caché para muchos de los puntos finales con control de acceso y puedo verlos después de cerrar la sesión (y verificar los datos de la sesión para asegurarme de que la clave es removido).
Algunos detalles...
Uso de flask con session para la información de inicio de sesión, no de inicio de sesión de matraz.
Alojamiento en un VPS administrado que utiliza Phusion Passenger como una interfaz WSGI para Apache
No tengo archivos de configuración en uso para Apache ... solo valores predeterminados en este momento.
El sitio web tiene muy poco tráfico... Prolly solo yo y los bots en este momento. :)
Mi archivo passenger_wsgi :
import sys, os from datetime import timedelta INTERP = "/home/<website>/venv1/bin/python3" #INTERP is present twice so that the new Python interpreter knows the actual executable path if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) # def application(environ, start_response): # start_response('200 OK', [('Content-type', 'text/plain')]) # return ["Hello, world!"] sys.path.append(os.getcwd()) from app import app as applicationDespués de iniciar sesión, las cosas funcionan como se esperaba. Después de cerrar la sesión, todavía puedo acceder a los puntos finales que se supone que tienen control de acceso y veo repetidamente esta "evidencia" cuando inspecciono el tráfico de la red en mi navegador:
Summary URL: https://<website>/<endpoint> <---- an endpoint covered by @login_required Status: 200 Source: Memory Cache Request No request, served from the memory cache. Response Content-Type: text/html; charset=utf-8 Expires: Wed, 22 Dec 2021 17:14:00 GMT Date: Wed, 22 Dec 2021 17:04:00 GMT Content-Length: 23 Cache-Control: max-age=600 Vary: User-Agent Status: 200 OK x-powered-by: Phusion Passenger 5.0.30 Server: ApacheEntonces mis preguntas son estas...
flask-login menos que sea curativo.Humildemente presento mi pregunta a las personas que se ocupan de estas pilas.
A partir de la versión 5.0, Passenger agregará de forma "útil" encabezados de control de caché a las respuestas que considere 'accesibles en caché'.
Para detener esto, su aplicación debe agregar el encabezado Cache-Control: no-store .
Para hacer esto globalmente en Flask como se describe aquí :
@app.after_request def add_header(response): # response.cache_control.no_store = True if 'Cache-Control' not in response.headers: response.headers['Cache-Control'] = 'no-store' return response Si desea ser más exigente y solo quiere hacer esto para las rutas que requieren un inicio de sesión, puede crear su propia extensión para el decorador login_required para hacer esto para sus rutas que requieren inicios de sesión (o un decorador completamente separado)
from flask import make_response from flask_login import login_required as _login_required def login_required(f): # apply the usual login_required decorator decorated = _login_required(f) def cache_no_store_login_required_view(*args, **kwargs): resp = make_response(decorated(*args, **kwargs)) # add the cache-control header to the response resp.headers['Cache-Control'] = 'no-store' return resp return cache_no_store_login_required_viewO como decorador independiente para establecer sin tiendas...
from functools import wraps def cache_no_store(f): @wraps(f) def decorated_view(*args, **kwargs): resp = make_response(f(*args, **kwargs)) resp.headers['Cache-Control'] = 'no-store' @app.route('/protected') @cache_no_store @login_required def my_route(): # ...