Der geheime Schlüssel wurde in der Flask-Sitzung mit der Flask-Session-Erweiterung nicht festgelegt

79

Im Moment verwende ich eine Flask-Session einer Drittanbieter-Bibliothek und habe kein Glück, dass eine Sitzung funktioniert.

Wenn ich eine Verbindung zu meiner Site herstelle, wird folgende Fehlermeldung angezeigt:

RuntimeError: Die Sitzung ist nicht verfügbar, da kein geheimer Schlüssel festgelegt wurde. Setzen Sie den secret_key in der Anwendung auf etwas Einzigartiges und Geheimes.

Unten ist mein Servercode.

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()

Wie Sie sehen können, setze ich den geheimen Schlüssel der App. Was mache ich falsch?

Gibt es andere Sitzungsoptionen?

Weitere Informationen: Ausführen von Python 2.7 unter Linux Mint

Vollpaste:

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
quelle
Was ist der vollständige Traceback der Ausnahme?
Martijn Pieters
Und welche Version von verwenden Flask-SessionSie? Ich kann in der aktuellen Projektquelle keinen Hinweis auf diese Ausnahme finden .
Martijn Pieters
@MartijnPieters Irgendeine Idee, wie ich das herausfinden könnte? Ich habe gerade eine Pip-Installation dafür gemacht
MintyAnt
Die Ausnahmemeldung wurde bereits gefunden. Es ist in Flask selbst, nicht in Flask-Session.
Martijn Pieters
@MartijnPieters Ich habe den vollständigen Traceback hinzugefügt. Es erscheint, wenn ich versuche, den Schlüssel 'userId' zu setzen, wie Sie sehen können
MintyAnt

Antworten:

92

In Ihrem Fall wird die Ausnahme von der NullSessionInterfaceSitzungsimplementierung ausgelöst. Dies ist der Standard-Sitzungstyp, wenn Sie Flask-Session verwenden. Das liegt daran, dass Sie Flask die SESSION_TYPEKonfiguration nie wirklich geben . Es reicht nicht aus , es in Ihrem Modul als global festzulegen. Der Flask-Session-Schnellstart-Beispielcode legt zwar einen globalen Wert fest , verwendet dann jedoch das aktuelle Modul durch Aufrufen als Konfigurationsobjekt .app.config.from_object(__name__)

Diese Standardeinstellung ist bei Flask 0.10 oder neuer nicht sehr sinnvoll. NullSessionmag mit Flask 0.8 oder 0.9 sinnvoll gewesen sein, aber in der aktuellen Version wird die flask.session.NullSessionKlasse als Fehlersignal verwendet. In Ihrem Fall erhalten Sie jetzt die falsche Fehlermeldung.

Stellen Sie die SESSION_TYPEKonfigurationsoption auf etwas anderes ein. Wählen Sie eine von redis, memcached, filesystemoder mongodb, und stellen Sie sicher , dass es setzen in app.config(direkt oder über die verschiedenen Config.from_*Methoden ).

Für einen schnellen Test ist es am filesystemeinfachsten , ihn einzustellen. Es gibt dort genug Standardkonfiguration, damit dies ohne zusätzliche Abhängigkeiten funktioniert:

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

    sess.init_app(app)

    app.debug = True
    app.run()

Wenn Sie diesen Fehler sehen und Flask-Session nicht verwenden, ist beim Einstellen des Geheimnisses ein Fehler aufgetreten. Wenn Sie eine Wache wie oben einstellen app.config['SECRET_KEY']oder diese Fehlermeldung erhalten, wird Ihre Flask-App wahrscheinlich über einen WSGI-Server ausgeführt, der Ihr Flask-Projekt als Modul importiert , und der Block wird nie ausgeführt.app.secret_keyif __name__ == "__main__":__name__ == "__main__"

Es ist sowieso immer besser, die Konfiguration für Flask-Apps in einer separaten Datei zu verwalten .

Martijn Pieters
quelle
3
Beachten Sie, dass die Verwendung app.secret_keyeine schlechte Praxis ist. Es ist besser, einen geheimen Schlüssel über das app.configObjekt festzulegen, damit Sie die Konfiguration in eine externe Datei auslagern können.
Miguel
4
Hinweis für Heroku-Benutzer, die hier gelandet sind: Ich habe das Beispiel hier erst zum Laufen gebracht, als ich app.secret_key = ...aus dem if- Block herausgezogen bin - was im Nachhinein sinnvoll ist, da Heroku die App über Gunicorn ausführt, was bedeutet, dass der if __name__ == "__main__":Block nie eingegeben wird.
Pascal
'Setzen Sie den geheimen Schlüssel außerhalb von if name ==' main ':' Die Antwort hier von stackoverflow.com/users/2900124/hayden unten ist eine bessere Antwort (funktioniert auf einem gehosteten Server, während dies nicht der
Fall war
@ ng10: Diese Antwort gilt, wenn Sie Flask-Session nicht verwenden . Das Problem bei der Frage hier ist, dass die Fehlermeldung, die Sie bei der Verwendung von Flask-Session sehen, nicht hilfreich und falsch ist. Wenn Sie die Fehlermeldung sehen, wenn Sie Flask-Session nicht verwenden, gilt möglicherweise die andere Antwort. Ich habe die Antwort aktualisiert, um beide Optionen anzusprechen.
Martijn Pieters
1
@iamai: das ist der Abschnitt Flask-Session Configuration dokumentiert ; Für Mongodb lautet der Standarddatenbankname flask_sessionund die Standardsammlung wird aufgerufen sessions.
Martijn Pieters
58

Setzen Sie den geheimen Schlüssel außerhalb von 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()

Wenn Sie Ihre App durch Ausführen starten, wird flask runder if __name__ == '__main__':Block übersprungen. Wenn Sie es nicht überspringen möchten, führen Sie es aus mit python app.py.

Hayden
quelle
Ich verwende eine Flask-App auf einem Amazon Ec2 Apache2 Ubuntu-Server und verwende oauth2.0, um auf Google Kalenderinformationen zuzugreifen. Diese Antwort ist die einfache Änderung, mit der es funktioniert hat. Vielen Dank!
Jas
Dies ist eine Antwort auf eine andere Frage , bei der der Sitzungstyp korrekt konfiguriert wurde oder Sie Flask-Session überhaupt nicht verwenden, aber kein Geheimnis festgelegt wurde, da der WSGI-Server das Modul mit Import geladen hat und nicht als Hauptskript.
Martijn Pieters
13

Versuche dies:

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

Und entfernen Sie Ihre app.secret_keyAufgabe unten.

Miguel
quelle
Ich habe es versucht, kein Glück, der gleiche Fehler. Ich kann den
Beitragscode