Python 使用 Flask 会话时出现内部服务器错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18139910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:59:06  来源:igfitidea点击:

Internal Server Error when using Flask session

pythonsessioncookiesflask

提问by sedavidw

I want to save an ID between requests, using Flask sessioncookie, but I'm getting an Internal Server Erroras result, when I perform a request.

我想使用 Flask sessioncookie在请求之间保存一个 ID ,但是Internal Server Error当我执行请求时,我得到了一个结果。

I prototyped a simple Flask app for demonstrating my problem:

我设计了一个简单的 Flask 应用程序来演示我的问题:

#!/usr/bin/env python

from flask import Flask, session

app = Flask(__name__)

@app.route('/')
def run():
    session['tmp'] = 43
    return '43'

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

Why I can't store the sessioncookie with the following value when I perform the request?

为什么我session在执行请求时无法存储具有以下值的cookie?

采纳答案by falsetru

According to Flask sessions documentation:

根据Flask 会话文档

... What this means is that the user could look at the contents of your cookie but not modify it, unless they know the secret key used for signing.

In order to use sessions you have to set a secret key.

...这意味着用户可以查看您的 cookie 的内容但不能修改它,除非他们知道用于签名的密钥。

为了使用会话,您必须设置一个密钥

Set secret key. And you should return string, not int.

设置密钥。你应该返回字符串,而不是整数。

#!/usr/bin/env python

from flask import Flask, session

app = Flask(__name__)

@app.route('/')
def run():
    session['tmp'] = 43
    return '43'

if __name__ == '__main__':
    app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
    app.run()

回答by joshlsullivan

Under app = Flask(__name__)place this: app.secret_key = os.urandom(24).

下面app = Flask(__name__)放置这个:app.secret_key = os.urandom(24)

回答by ivanleoncz

As @falsetrumentioned, you have to set a secret key.

正如@falsetru提到的,您必须设置一个密钥。

Before sending the sessioncookie to the user's browser, Flask signs the cookies cryptographically, and that doesn't mean that you cannot decode the cookie. I presume that Flask keeps track of the signed cookies, so it can perform it's own 'magic', in order to determine if the cookie that was sent along with the request (request headers), is a valid cookie or not.

在将sessioncookie发送到用户的浏览器之前,Flask 会对 cookie 进行加密签名,这并不意味着您无法对 cookie 进行解码。我认为 Flask 会跟踪签名的 cookie,因此它可以执行自己的“魔术”,以确定与请求(请求标头)一起发送的 cookie 是否是有效的 cookie。

Some methods that you may use, all related with Flask class instance, generally defined as app:

您可能会使用的一些方法,都与 Flask 类实例相关,一般定义为app

  • defining the secret_keyvariable for appobject

    app.secret_key = b'6hc/_gsh,./;2ZZx3c6_s,1//'
    
  • using the config()method

    app.config['SECRET_KEY'] = b'6hc/_gsh,./;2ZZx3c6_s,1//'
    
  • using an external configuration file for the entire Flask application

    $ grep pyfile app.py
    app.config.from_pyfile('flask_settings.cfg')
    
    $ cat flask_settings.py
    SECRET_KEY = b'6hc/_gsh,./;2ZZx3c6_s,1//'
    
  • 定义对象的secret_key变量app

    app.secret_key = b'6hc/_gsh,./;2ZZx3c6_s,1//'
    
  • 使用config()方法

    app.config['SECRET_KEY'] = b'6hc/_gsh,./;2ZZx3c6_s,1//'
    
  • 为整个 Flask 应用程序使用外部配置文件

    $ grep pyfile app.py
    app.config.from_pyfile('flask_settings.cfg')
    
    $ cat flask_settings.py
    SECRET_KEY = b'6hc/_gsh,./;2ZZx3c6_s,1//'
    

Here's an example (an adaptation from this article), focused on providing a more clearer picture of Flask sessioncookie, considering the participation of both Client and Server sides:

下面是一个例子(改编自这篇文章),侧重于提供更清晰的 Flask sessioncookie图像,考虑到 Client 和 Server 双方的参与:

from flask import Flask, request, session                                       
import os                                                                       

app = Flask(__name__)                                                           

@app.route('/')                                                                 
def f_index():                                                               
    # Request Headers, sent on every request                                    
    print("\n\n\n[Client-side]\n", request.headers)                             
    if 'visits' in session:                                                     
        # getting value from session dict (Server-side) and incrementing by 1   
        session['visits'] = session.get('visits') + 1                           
    else:                                                                       
        # first visit, generates the key/value pair {"visits":1}                
        session['visits'] = 1                                                   
        # 'session' cookie tracked from every request sent                          
        print("[Server-side]\n", session)                                           
    return "Total visits:{0}".format(session.get('visits'))                     


if __name__ == "__main__":                                                      
    app.secret_key = os.urandom(24)                                             
    app.run()

Here's the output:

这是输出:

$ python3 sessions.py 
* Serving Flask app "sessions" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

[Client-side]
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Host: 127.0.0.1:5000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5

[Server-side]
<SecureCookieSession {'visits': 1}>
127.0.0.1 - - [12/Oct/2018 14:27:05] "GET / HTTP/1.1" 200 -


[Client-side]
Upgrade-Insecure-Requests: 1
Cookie: session=eyJ2aXNpdHMiOjF9.DqKHCQ.MSZ7J-Zicehb6rr8qw43dCVXVNA  # <--- session cookie
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Host: 127.0.0.1:5000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5

[Server-side]
<SecureCookieSession {'visits': 2}>
127.0.0.1 - - [12/Oct/2018 14:27:14] "GET / HTTP/1.1" 200 -


You may have noticed that in the example above, I'm using the oslib and the urandom()function, in order to generate Flask's secret key, right?

您可能已经注意到,在上面的示例中,我使用了oslib 和urandom()函数,以便生成 Flask 的密钥,对吗?

From the official doc:

来自官方文档

How to generate good secret keys

A secret key should be as random as possible. Your operating system has ways to generate pretty random data based on a cryptographic random generator. Use the following command to quickly generate a value for Flask.secret_key (or SECRET_KEY):

$ python -c 'import os; print(os.urandom(16))'

b'_5#y2L"F4Q8z\n\xec]/'

如何生成好的秘钥

密钥应尽可能随机。您的操作系统可以根据加密随机生成器生成相当随机的数据。使用以下命令快速生成 Flask.secret_key(或 SECRET_KEY)的值:

$ python -c '导入操作系统;打印(os.urandom(16))'

b'_5#y2L"F4Q8z\n\xec]/'



PLUS NOTE

加注

As you can see, the creators of Flask support the practice of using os.urandom()for building the Flask secret key, from older versions of the tool to its latest version. So: why @joshlsullivan'sanswer received downvotes (deserves an upvote) and why @MikhailKashkinwrites that, using os.urandom()is terrible idea, are mysteries.

如您所见,Flask 的创建者支持使用os.urandom()用于构建 Flask 密钥的做法,从该工具的旧版本到最新版本。所以:为什么@joshlsullivan 的回答得到了反对票(应该得到赞成票)以及为什么@MikhailKashkin写道,使用os.urandom()是一个糟糕的主意,是个谜。