секретный ключ не установлен в сеансе фляги с использованием расширения Flask-Session

83

Прямо сейчас я использую стороннюю библиотеку Flask-Session, и мне не удается заставить сеанс работать.

Когда я подключаюсь к своему сайту, я получаю следующую ошибку:

RuntimeError: сеанс недоступен, так как не был установлен секретный ключ. Установите secret_key в приложении на что-нибудь уникальное и секретное.

Ниже мой код сервера.

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

Как видите, я установил секретный ключ приложения. Что я делаю неправильно?

Есть ли другие варианты сеанса?

Дополнительная информация: Запуск Python 2.7 на Linux Mint

Полная паста:

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
источник
Что такое полная трассировка исключения?
Мартейн Питерс
А какой версией Flask-Sessionпользуетесь? Я не могу найти ссылку на это исключение в текущем источнике проекта .
Мартейн Питерс
@MartijnPieters Есть идеи, как я мог это понять? Я только что установил для него pip
MintyAnt
Сообщение об исключении уже обнаружено; это в самом Flask, а не во Flask-Session.
Мартин Питерс
@MartijnPieters Я добавил полную трассировку. Он появляется, когда я пытаюсь установить ключ userId, как вы можете видеть
MintyAnt

Ответы:

96

В вашем случае исключение вызывается NullSessionInterfaceреализацией сеанса, которая является типом сеанса по умолчанию при использовании Flask-Session. Это потому, что вы никогда не передаете SESSION_TYPEконфигурацию Flask ; это не достаточно , чтобы установить его в качестве глобального в вашем модуле. Код примера быстрого запуска Flask-Session действительно устанавливает глобальный, но затем использует текущий модуль в качестве объекта конфигурации, вызывая app.config.from_object(__name__).

Это значение по умолчанию не имеет особого смысла с Flask 0.10 или новее; NullSessionмог иметь смысл с Flask 0.8 или 0.9, но в текущей версии flask.session.NullSessionкласс используется как сигнал об ошибке. В вашем случае теперь выдается неправильное сообщение об ошибке.

Установите SESSION_TYPEдля параметра конфигурации другое значение. Выберите один из redis, memcached, filesystemили mongodb, и убедитесь , чтобы установить его в app.config(непосредственно или через различные Config.from_*методы ).

Для быстрого тестирования filesystemпроще всего установить его ; там достаточно конфигурации по умолчанию, чтобы она работала без дополнительных зависимостей:

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

    sess.init_app(app)

    app.debug = True
    app.run()

Если вы видите эту ошибку и не используете Flask-Session, значит, что-то пошло не так с установкой секрета. Если вы устанавливаете app.config['SECRET_KEY']или app.secret_keyиспользуете if __name__ == "__main__":охранник, как указано выше, и вы получаете эту ошибку, то вы, вероятно, запускаете свое приложение Flask через сервер WSGI, который импортирует ваш проект Flask как модуль , и __name__ == "__main__"блок никогда не запускается.

В любом случае всегда лучше управлять конфигурацией приложений Flask в отдельном файле .

Мартейн Питерс
источник
3
Обратите внимание, что использование app.secret_key- плохая практика. Лучше установить секретный ключ через app.configобъект, что позволяет выгрузить конфигурацию во внешний файл.
Мигель
4
Примечание для пользователей Heroku, которые здесь оказались: я не заставил этот пример работать, пока я не app.secret_key = ...вышел из блока if - что, оглядываясь назад, имеет смысл, поскольку Heroku запускает приложение через gunicorn, что означает, что if __name__ == "__main__":блок никогда не вводится.
Паскаль
'Установить секретный ключ вне if name ==' main ':' ответ здесь stackoverflow.com/users/2900124/hayden ниже - лучший ответ (работал на размещенном сервере, а этот - нет)
ng10
@ ng10: этот ответ применим, когда вы не используете Flask-Session . Проблема в том, что сообщение об ошибке, которое вы видите при использовании Flask-Session, бесполезно и неправильно. Если вы видите сообщение об ошибке, когда не используете Flask-Session, то может применяться другой ответ. Я обновил ответ, чтобы рассмотреть оба варианта.
Мартейн Питерс
1
@iamai: это задокументировано Колба-Session Configuration раздел ; для mongodb имя базы данных по умолчанию - flask_sessionи вызывается коллекция по умолчанию sessions.
Мартейн Питерс
59

Установите секретный ключ вне 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()

При запуске приложения, запустив блок получает пропускаются. Если вы не хотите его пропускать, используйте .flask runif __name__ == '__main__':python app.py

Хайден
источник
Я запускаю приложение Flask на сервере Ubuntu amazon ec2 apache2, используя oauth2.0 для доступа к информации календаря Google. Этот ответ - простая модификация, которая заставила его работать. Спасибо!
jas
Это ответ на другой вопрос , в котором тип сеанса был настроен правильно или вы вообще не используете Flask-Session, но секрет не был установлен, потому что сервер WSGI загрузил модуль с импортом, а не как основной сценарий.
Мартейн Питерс
14

Попробуй это:

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

И удалите свое app.secret_keyзадание внизу.

Мигель
источник
Я попробовал, не повезло, та же ошибка. Я могу обновить код сообщений, если хотите
MintyAnt