clave secreta no configurada en la sesión del matraz, usando la extensión Flask-Session

83

En este momento estoy usando un matraz de biblioteca de terceros Flask-Session y no tengo suerte para que una sesión funcione.

Cuando me conecto a mi sitio, aparece el siguiente error:

RuntimeError: la sesión no está disponible porque no se estableció una clave secreta. Establezca la clave_secreta de la aplicación en algo único y secreto.

A continuación se muestra el código de mi servidor.

from flask import Flask, session
from flask.ext.session import Session

SESSION_TYPE = 'memcache'

app = Flask(__name__)
sess = Session()

nextId = 0

def verifySessionId():
    global nextId

    if not 'userId' in session:
        session['userId'] = nextId
        nextId += 1
        sessionId = session['userId']
        print ("set userid[" + str(session['userId']) + "]")
    else:
        print ("using already set userid[" + str(session['userId']) + "]")
    sessionId = session.get('userId', None)
    return sessionId

@app.route("/")
def hello():
    userId = verifySessionId()
    print("User id[" + str(userId) + "]")
    return str(userId)

if __name__ == "__main__":
    app.secret_key = 'super secret key'

    sess.init_app(app)

    app.debug = True
    app.run()

Como puede ver, configuro la clave secreta de la aplicación. ¿Qué estoy haciendo mal?

¿Hay otras opciones de sesión?

Otra información: Ejecución de Python 2.7 en Linux Mint

Pasta completa:

Traceback (most recent call last):
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/sean/code/misc/session/sessiontest.py", line 27, in hello
    userId = verifySessionId()
  File "/home/sean/code/misc/session/sessiontest.py", line 16, in verifySessionId
    session['userId'] = nextId
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/werkzeug/local.py", line 341, in __setitem__
    self._get_current_object()[key] = value
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/sessions.py", line 126, in _fail
    raise RuntimeError('the session is unavailable because no secret '
RuntimeError: the session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.
MintyAnt
fuente
¿Cuál es el rastreo completo de la excepción?
Martijn Pieters
¿Y qué versión de Flask-Sessionestás usando? No puedo encontrar ninguna referencia de esa excepción en la fuente actual del proyecto .
Martijn Pieters
@MartijnPieters ¿Alguna idea de cómo podría averiguarlo? Acabo de hacer una instalación de pip para él
MintyAnt
Ya encontré el mensaje de excepción; está en Flask mismo, no en Flask-Session.
Martijn Pieters
@MartijnPieters Agregué el rastreo completo. Aparece cuando intento establecer la clave 'userId', como puede ver
MintyAnt

Respuestas:

96

En su caso, la excepción la NullSessionInterfacegenera la implementación de la sesión, que es el tipo de sesión predeterminado cuando usa Flask-Session. Eso es porque nunca le das la SESSION_TYPEconfiguración a Flask ; no es suficiente establecerlo como global en su módulo. El código de ejemplo de inicio rápido de Flask-Session establece un global, pero luego usa el módulo actual como un objeto de configuración al llamar app.config.from_object(__name__).

Este valor predeterminado no tiene mucho sentido con Flask 0.10 o más reciente; NullSessionpuede haber tenido sentido con Flask 0.8 o 0.9, pero en la versión actual la flask.session.NullSessionclase se usa como señal de error. En su caso, ahora le da el mensaje de error incorrecto.

Establezca la SESSION_TYPEopción de configuración en otra cosa. Escoja uno de redis, memcached, filesystemo mongodb, y asegúrese de ponerlo en app.config(directamente oa través de los diversos Config.from_*métodos ).

Para una prueba rápida, configurarlo en filesystemes más fácil; hay suficiente configuración predeterminada para que funcione sin dependencias adicionales:

if __name__ == "__main__":
    app.secret_key = 'super secret key'
    app.config['SESSION_TYPE'] = 'filesystem'

    sess.init_app(app)

    app.debug = True
    app.run()

Si ve este error y que está no está usando el matraz de sesión, entonces algo tiene mal se ha ido con el establecimiento el secreto. Si está configurando app.config['SECRET_KEY']o app.secret_keyen un if __name__ == "__main__":guardia como el anterior y obtiene este error, entonces probablemente esté ejecutando su aplicación Flask a través de un servidor WSGI que importa su proyecto Flask como un módulo , y el __name__ == "__main__"bloque nunca se ejecuta.

De todos modos, siempre es mejor administrar la configuración de las aplicaciones de Flask en un archivo separado .

Martijn Pieters
fuente
3
Tenga en cuenta que usar app.secret_keyes una mala práctica. Es mejor establecer la clave secreta a través del app.configobjeto, lo que le permite descargar la configuración a un archivo externo.
Miguel
4
Nota para los usuarios de Heroku que terminan aquí: no obtuve el ejemplo aquí hasta que app.secret_key = ...salí del bloque if , lo que en retrospectiva tiene sentido ya que Heroku ejecuta la aplicación a través de gunicorn, lo que significa que el if __name__ == "__main__":bloque nunca se ingresa.
Pascal
'Establezca la clave secreta fuera de if name ==' main ':' la respuesta aquí por stackoverflow.com/users/2900124/hayden a continuación es una mejor respuesta (funcionó en el servidor alojado, mientras que este no lo hizo)
ng10
@ ng10: esa respuesta se aplica cuando no está utilizando Flask-Session . El problema en la pregunta aquí es que el mensaje de error que ve cuando usa Flask-Session no es útil y es incorrecto. Si ve el mensaje de error cuando no usa Flask-Session, entonces podría aplicarse la otra respuesta. Actualicé la respuesta para abordar ambas opciones.
Martijn Pieters
1
@iamai: eso está documentado en la sección Configuración de sesión de matraz ; para mongodb, el nombre de la base de datos predeterminado es flask_session, y se llama a la colección predeterminada sessions.
Martijn Pieters
59

Establecer la clave secreta fuera de if __name__ == '__main__':

app.py:

from flask import Flask, session

app = Flask(__name__)
app.secret_key = "super secret key"

@app.route("/")
...

if __name__ == '__main__':
    app.debug = True
    app.run()

Cuando inicia su aplicación ejecutando flask runel if __name__ == '__main__':bloque se omite. Si no desea omitirlo, ejecute python app.py.

Hayden
fuente
Estoy ejecutando una aplicación de matraz en un servidor Ubuntu de amazon ec2 apache2, usando oauth2.0 para acceder a la información del calendario de Google. Esta respuesta es la simple modificación que lo hizo funcionar. ¡Gracias!
jas
Esta es una respuesta a una pregunta diferente , una en la que el tipo de sesión se ha configurado correctamente o no está utilizando Flask-Session en absoluto, pero no se ha establecido ningún secreto porque el servidor WSGI ha cargado el módulo con la importación y no como el guión principal.
Martijn Pieters
14

Prueba esto:

app = Flask(__name__)
app.config['SESSION_TYPE'] = 'memcached'
app.config['SECRET_KEY'] = 'super secret key'
sess = Session()

Y elimine su app.secret_keytarea en la parte inferior.

Miguel
fuente
Le di una oportunidad, sin suerte, el mismo error. Puedo actualizar el código de publicación si lo desea
MintyAnt