Tengo una aplicación Flask que usa un decorador personalizado para verificar un token de inicio de sesión de AWS Cognito pasado en un atributo de encabezado HTTP. El proceso incluye actualizar el token (que está más allá del alcance de esta pregunta). Una vez que obtenga el token actualizado, me gustaría actualizar el atributo del encabezado para incluir el token actualizado y salir. Dado que la propiedad Flask/Werkzeug request.headers es inmutable, no puedo actualizarla por medios normales.
¿Cómo puedo actualizar los encabezados en el contexto de este decorador? ¿Hay una mejor manera que no estoy pensando?
Aquí hay un código de muestra que demuestra el problema:
def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): token = request.headers.get('X-MyApp-Auth') if not token: return redirect(url_for('login', next=request.url)) # Test for expired token (pseudocode) if expired(token): # Refresh the token (pseudocode) new_token = refresh(refresh_token) # This is the part where the immutability gets me stuck request.headers.set('X-MyApp-Auth', new_token) return f(*args, **kwargs) return decorated_functionEste ejemplo envuelve la aplicación Flask en un middleware WSGI personalizado que modifica el entorno WSGI antes del manejo de solicitudes Flask:
from flask import Flask, request, jsonify class InterceptRequestMiddleware: def __init__(self, wsgi_app): self.wsgi_app = wsgi_app def __call__(self, environ, start_response): environ['HTTP_USER_AGENT'] = 'foobar' return self.wsgi_app(environ, start_response) app = Flask(__name__) app.wsgi_app = InterceptRequestMiddleware(app.wsgi_app) @app.route('/') def index(): return jsonify({'headers': {k: v for k, v in request.headers}}) if __name__ == '__main__': app.run(debug=True)Enlaces:
request.headers son los encabezados HTTP que su servidor recibió de la aplicación del cliente, por lo que tiene sentido que no pueda actualizarlos. Es posible que desee establecer encabezados de respuesta que se pueden crear siguiendo este hilo: ¿Cómo configuro los encabezados de respuesta en Flask?
Tengo el mismo problema: tengo un decorador que realiza la limpieza, la autenticación y proporciona información de autorización utilizada en toda la aplicación.
Dos puntos de diseño con request.headers hacen que sea difícil trabajar con ellos. a) los datos son inmutables, b) las claves no distinguen entre mayúsculas y minúsculas.
Una forma de evitar esto es copiar los encabezados de solicitud en otra estructura de datos que tenga contenido aceptable de buena fe en lugar de cualquier cosa que proporcione el pirata informático.
from requests.structures import CaseInsensitiveDict copy = CaseInsensitiveDict() for k, v in request.headers: copy[k] = vEsto se puede ampliar para filtrar en la lista blanca los encabezados necesarios, limpiar los valores según https://owasp.org/www-project-top-ten/2017/A1_2017-Injection y modificar el bloque de parámetros con información privada personalizada.
Este método no actualiza el objeto request.headers. Debe desarrollar un patrón en el que los bloques de parámetros del usuario de su aplicación sean de confianza y los bloques proporcionados por el matraz no sean de confianza.