Error interno del servidor al usar la sesión de Flask

Quiero guardar una ID entre las solicitudes, utilizando la cookie de session Flask, pero como resultado obtengo un Internal Server Error cuando realizo una solicitud.

Prototipé una aplicación Flask simple para demostrar mi problema:

 #!/usr/bin/env python from flask import Flask, session app = Flask(__name__) @app.route('/') def run(): session['tmp'] = 43 return '43' if __name__ == '__main__': app.run() 

¿Por qué no puedo almacenar la cookie de session con el siguiente valor cuando realizo la solicitud?

Según la documentación de las sesiones de Flask :

… Lo que esto significa es que el usuario puede mirar el contenido de su cookie pero no modificarla, a menos que sepa la clave secreta utilizada para firmar.

Para utilizar las sesiones tienes que configurar una clave secreta .

Establecer clave secreta . Y deberías devolver cadena, no int.

 #!/usr/bin/env python from flask import Flask, session app = Flask(__name__) @app.route('/') def run(): session['tmp'] = 43 return '43' if __name__ == '__main__': app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' app.run() 

Bajo app = Flask(__name__) coloca esto: app.secret_key = os.urandom(24) .

Como mencionó @falsetru , debe establecer una clave secreta.

Antes de enviar la cookie de session al navegador del usuario, Flask firma las cookies de forma criptográfica, y eso no significa que no pueda decodificar la cookie. Supongo que Flask realiza un seguimiento de las cookies firmadas, para que pueda realizar su propia ‘magia’, a fin de determinar si la cookie que se envió junto con la solicitud (encabezados de solicitud), es una cookie válida o no.

Algunos métodos que puede utilizar, todos relacionados con la instancia de la clase Flask, generalmente se definen como app :

  • definiendo la variable secret_key para el objeto de app

     app.secret_key = b'6hc/_gsh,./;2ZZx3c6_s,1//' 
  • usando el método config()

     app.config['SECRET_KEY'] = b'6hc/_gsh,./;2ZZx3c6_s,1//' 
  • utilizando un archivo de configuración externo para toda la aplicación Flask

     $ grep pyfile app.py app.config.from_pyfile('flask_settings.cfg') $ cat flask_settings.py SECRET_KEY = b'6hc/_gsh,./;2ZZx3c6_s,1//' 

Aquí hay un ejemplo (una adaptación de este artículo ), centrado en proporcionar una imagen más clara de la cookie de session de Flask, considerando la participación de los lados del Cliente y del Servidor:

 from flask import Flask, request, session import os app = Flask(__name__) @app.route('/') def f_index(): # Request Headers, sent on every request print("\n\n\n[Client-side]\n", request.headers) if 'visits' in session: # getting value from session dict (Server-side) and incrementing by 1 session['visits'] = session.get('visits') + 1 else: # first visit, generates the key/value pair {"visits":1} session['visits'] = 1 # 'session' cookie tracked from every request sent print("[Server-side]\n", session) return "Total visits:{0}".format(session.get('visits')) if __name__ == "__main__": app.secret_key = os.urandom(24) app.run() 

Aquí está la salida:

 $ python3 sessions.py * Serving Flask app "sessions" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) [Client-side] Upgrade-Insecure-Requests: 1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Connection: keep-alive Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.5 [Server-side]  127.0.0.1 - - [12/Oct/2018 14:27:05] "GET / HTTP/1.1" 200 - [Client-side] Upgrade-Insecure-Requests: 1 Cookie: session=eyJ2aXNpdHMiOjF9.DqKHCQ.MSZ7J-Zicehb6rr8qw43dCVXVNA # <--- session cookie Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Connection: keep-alive Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.5 [Server-side]  127.0.0.1 - - [12/Oct/2018 14:27:14] "GET / HTTP/1.1" 200 - 

Puede que hayas notado que en el ejemplo anterior, estoy usando os lib y la función urandom() para generar la clave secreta de Flask, ¿verdad?

Del documento oficial :

Cómo generar buenas claves secretas.

Una clave secreta debe ser lo más aleatoria posible. Su sistema operativo tiene formas de generar datos bastante aleatorios basados ​​en un generador criptográfico aleatorio. Use el siguiente comando para generar rápidamente un valor para Flask.secret_key (o SECRET_KEY):

$ python -c ‘import os; imprimir (os.urandom (16)) ‘

b’_5 # y2L “F4Q8z \ n \ xec] / ‘


MÁS NOTA

Como puede ver, los creadores de Flask admiten la práctica de usar os.urandom() para crear la clave secreta de Flask, desde las versiones más antiguas de la herramienta hasta su última versión. Entonces: ¿por qué la respuesta de @ joshlsullivan recibió votos a favor (merece un voto a favor ) y por qué @MikhailKashkin escribe que, usar os.urandom() es una idea terrible, son misterios.