tajny klucz nie jest ustawiony w sesji flask przy użyciu rozszerzenia Flask-Session

83

W tej chwili używam biblioteki Flask-Session innej firmy i nie mam szczęścia, aby sesja działała.

Kiedy łączę się z moją witryną, pojawia się następujący błąd:

RuntimeError: sesja jest niedostępna, ponieważ nie ustawiono tajnego klucza. Ustaw klucz tajny w aplikacji na coś unikalnego i tajnego.

Poniżej znajduje się mój kod serwera.

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

Jak widać, ustawiam tajny klucz aplikacji. Co ja robię źle?

Czy są inne opcje sesji?

Inne informacje: Uruchamianie Pythona 2.7 na Linux Mint

Pełna pasta:

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
źródło
Jakie jest pełne śledzenie wyjątku?
Martijn Pieters
A jakiej wersji Flask-Sessionużywasz? Nie mogę znaleźć żadnego odniesienia do tego wyjątku w bieżącym źródle projektu .
Martijn Pieters
@MartijnPieters Masz jakiś pomysł, jak mogę to rozgryźć? Właśnie wykonałem instalację pip dla tego
MintyAnt
Odnalazłem już komunikat o wyjątku; jest w samym Flask, a nie w Flask-Session.
Martijn Pieters
@MartijnPieters Dodałem pełne śledzenie. Pojawia się, gdy próbuję ustawić klucz 'userId', jak widać
MintyAnt

Odpowiedzi:

96

W twoim przypadku wyjątek jest wywoływany przez NullSessionInterfaceimplementację sesji, która jest domyślnym typem sesji, gdy używasz Flask-Session. Dzieje się tak dlatego, że tak naprawdę nigdy nie przekazujesz SESSION_TYPEkonfiguracji Flask ; to nie wystarczy , aby ustawić go jako globalny w module. W kolbie sesji QuickStart przykładowy kod powoduje ustawienie globalne, ale wtedy używa bieżącego modułu jako obiekt konfiguracji poprzez wywołanie app.config.from_object(__name__).

To ustawienie domyślne nie ma większego sensu z Flask 0.10 lub nowszym; NullSessionmogło mieć sens z Flask 0.8 lub 0.9, ale w obecnej wersji flask.session.NullSessionklasa jest używana jako sygnał błędu. W twoim przypadku wyświetla teraz zły komunikat o błędzie.

Ustaw SESSION_TYPEopcję konfiguracji na coś innego. Wybierz jedną redis, memcached, filesystemlub mongodb, i upewnij się, aby ustawić go w app.config(bezpośrednio lub za pośrednictwem różnych Config.from_*metod ).

Aby przeprowadzić szybki test, filesystemnajłatwiej jest ustawić go na ; jest tam wystarczająco dużo domyślnej konfiguracji, aby działała bez dodatkowych zależności:

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

    sess.init_app(app)

    app.debug = True
    app.run()

Jeśli widzisz ten błąd i nie używasz Flask-Session, coś poszło nie tak z ustawieniem sekretu. Jeśli ustawiasz app.config['SECRET_KEY']lub jesteś app.secret_keyw if __name__ == "__main__":straży jak powyżej i otrzymujesz ten błąd, prawdopodobnie uruchamiasz aplikację Flask za pośrednictwem serwera WSGI, który importuje projekt Flask jako moduł , a __name__ == "__main__"blok nigdy nie jest uruchamiany.

W każdym razie zawsze lepiej jest zarządzać konfiguracją aplikacji Flask w osobnym pliku .

Martijn Pieters
źródło
3
Zauważ, że używanie app.secret_keyjest złą praktyką. Lepiej jest ustawić tajny klucz za pośrednictwem app.configobiektu, który umożliwia przeniesienie konfiguracji do pliku zewnętrznego.
Miguel
4
Uwaga dla użytkowników Heroku kończących tutaj: nie dostałem tego przykładu do pracy, dopóki nie app.secret_key = ...wyszedłem z bloku if - co z perspektywy czasu ma sens, ponieważ Heroku uruchamia aplikację przez gunicorn, co oznacza, że if __name__ == "__main__":blok nigdy nie jest wprowadzany.
Pascal
'Ustaw tajny klucz poza if name ==' main ':' odpowiedz tutaj przez stackoverflow.com/users/2900124/hayden poniżej jest lepszą odpowiedzią (działał na serwerze hostowanym, podczas gdy ten nie
działał
@ ng10: ta odpowiedź ma zastosowanie, gdy nie używasz Flask-Session . Problem w tym pytaniu polega na tym, że komunikat o błędzie, który widzisz podczas korzystania z Flask-Session, nie jest pomocny i błędny. Jeśli zobaczysz komunikat o błędzie, gdy nie używasz Flask-Session, może obowiązywać inna odpowiedź. Zaktualizowałem odpowiedź, aby uwzględnić obie opcje.
Martijn Pieters
1
@iamai: to jest udokumentowane w sekcji Konfiguracja sesji Flask ; w przypadku mongodb domyślną nazwą bazy danych jest flask_session, a wywoływana jest domyślna kolekcja sessions.
Martijn Pieters
59

Ustaw tajny klucz poza 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()

Po uruchomieniu aplikacji, uruchamiając blok dostaje pomijane. Jeśli nie chcesz go pominąć, biegnij z .flask runif __name__ == '__main__':python app.py

Hayden
źródło
Używam aplikacji Flask na serwerze Amazon EC2 Apache2 Ubuntu, używając oauth2.0, aby uzyskać dostęp do informacji kalendarza Google. Ta odpowiedź to prosta modyfikacja, która sprawiła, że ​​to zadziałało. Dziękuję Ci!
jas
To jest odpowiedź na inne pytanie , takie, w którym typ sesji został poprawnie skonfigurowany lub w ogóle nie używasz Flask-Session, ale nie ustawiono hasła, ponieważ serwer WSGI załadował moduł z importem, a nie jako główny skrypt.
Martijn Pieters
14

Spróbuj tego:

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

I usuń swoje app.secret_keyzadanie na dole.

Miguel
źródło
Dałem temu szansę, bez powodzenia, ten sam błąd. Mogę zaktualizować kod pocztowy, jeśli chcesz
MintyAnt