使用 Flask-Session 扩展,未在烧瓶会话中设置密钥

Posted

技术标签:

【中文标题】使用 Flask-Session 扩展,未在烧瓶会话中设置密钥【英文标题】:secret key not set in flask session, using the Flask-Session extension 【发布时间】:2014-11-22 17:20:55 【问题描述】:

现在我正在使用烧瓶 3rd 方库 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()

如您所见,我确实设置了应用程序密钥。我做错了什么?

还有其他会话选项吗?

其他信息: 在 Linux Mint 上运行 Python 2.7

完整粘贴:

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.

【问题讨论】:

【参考方案1】:

在您的情况下,NullSessionInterface 会话实现引发了异常,这是您使用 Flask-Session 时的默认会话类型。那是因为您实际上从未将 SESSION_TYPE 配置 提供给 Flask;在您的模块中将其设置为全局是不够。 Flask-Session quickstart example code 确实设置了一个全局,但随后通过调用 app.config.from_object(__name__) 将当前模块用作配置对象。

这个默认值对于 Flask 0.10 或更高版本没有多大意义; NullSession 可能对 Flask 0.8 或 0.9 有意义,但在当前版本中,flask.session.NullSession class 用作错误信号。在您的情况下,它现在会给您错误的错误消息。

SESSION_TYPE 配置选项设置为其他值。选择redismemcachedfilesystemmongodb 之一,并确保将其设置为app.config(直接或通过various Config.from_* methods)。

为了快速测试,将其设置为filesystem 是最简单的;那里有足够的默认配置可以在没有额外依赖项的情况下工作:

if __name__ == "__main__":
    # Quick test configuration. Please use proper Flask configuration options
    # in production settings, and use a separate file or environment variables
    # to manage the secret key!
    app.secret_key = 'super secret key'
    app.config['SESSION_TYPE'] = 'filesystem'

    sess.init_app(app)

    app.debug = True
    app.run()

如果您看到此错误并且您没有使用 Flask-Session,则说明设置密码有问题。如果您像上面一样在if __name__ == "__main__": 守卫中设置app.config['SECRET_KEY']app.secret_key 并且收到此错误,那么您可能是通过将您的Flask 项目导入为模块的WSGI 服务器运行您的Flask 应用程序 em>,并且永远不会运行 __name__ == "__main__" 块。

无论如何,manage configuration for Flask apps in a separate file 总是更好。

【讨论】:

@martijin Pieters:这个会话变量存储在哪里?例如,如果是 'mongodb',存储这些会话变量的数据库在哪里? @iamai: 记录了Flask-Session Configuration section;对于mongodb,默认数据库名称为flask_session,默认集合名为sessions 至少从烧瓶 1.1.2 开始(很可能更早),这个答案似乎非常错误。它声明您必须设置 SESSION_TYPE 并且仅列出会话存储在服务器端的选项。但这不是[当前]正确的。如果您成功设置了 SECRET_KEY,则默认会话类型会将会话存储在加密的 cookie 中(不是服务器端)。 IE:您不需要设置 SESSION_TYPE 以使其正常工作,您可以按照错误消息的提示设置 SECRET_KEY。 @PhilipCouling 这个答案特定于Flask-Session 扩展。您正在考虑基础 Flask。是的,对于基本 Flask 设置,SECRET_KEY 用于加密签名 cookie(cookie 未加密,内容可以轻松解码,但不能更改) . @PhilipCouling:这个问题很清楚;标题包含using the Flask-Session extension,并以开始>。如果您来这里寻找有关会话的基本 Flask 设置的信息,您需要参考 Flask API documentation 和 section on sessions in the Flask tutorial。【参考方案2】:

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 run 启动应用程序时,if __name__ == '__main__': 块将被跳过。如果您不想跳过它,请使用python app.py 运行。

【讨论】:

我正在亚马逊 ec2 apache2 Ubuntu 服务器上运行一个烧瓶应用程序,使用 oauth2.0 访问谷歌日历信息。这个答案是使它工作的简单修改。谢谢! 这是对不同问题的回答,其中会话类型已正确配置,或者您根本没有使用 Flask-Session,但未设置任何秘密因为 WSGI 服务器已经使用 import 加载了模块,而不是作为主脚本。 在生产环境中,您希望将机密存储在代码库之外,无论如何都在单独的配置文件中【参考方案3】:

试试这个:

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

并删除底部的 app.secret_key 分配。

【讨论】:

我试了一下,没有运气,同样的错误。如果您愿意,我可以更新帖子代码

以上是关于使用 Flask-Session 扩展,未在烧瓶会话中设置密钥的主要内容,如果未能解决你的问题,请参考以下文章

在 Elastic Beanstalk 中扩展实例会破坏 python 烧瓶应用程序的动态图像链接

带有烧瓶安全扩展的基于令牌的身份验证

Chrome 扩展程序未在 YouTube 的浏览器导航中加载

Flexbox溢出未在Chrome中扩展父容器

未在运行状况检查请求中设置 SNI 扩展 (Apache v.2.4.35)

Javascript 提示未在 ipad 上扩展