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

时间:2013-08-09 04:10:40

标签: python session cookies flask

我想使用Flask session Cookie在请求之间保存ID,但是当我执行请求时,我得到了Internal Server Error

我制作了一个简单的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()

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

3 个答案:

答案 0 :(得分:50)

根据Flask sessions documentation

  

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

     

要使用会话,必须设置密钥

设置密钥。你应该返回字符串,而不是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()

答案 1 :(得分:1)

@falsetru 所述,您必须设置一个秘密密钥。

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

您可以使用的某些方法都与Flask类实例相关,通常定义为app

  • 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//'
    

下面是一个示例(来自this article的改编版),该示例着重于考虑客户端和服务器端的参与,以提供更清晰的Flask session cookie图像:

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

以下是输出:

$ 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 -

您可能已经注意到,在上面的示例中,我使用os库和urandom()函数来生成Flask的秘密密钥,对吧?

来自the official doc

  

如何生成良好的秘密密钥

     

密钥应尽可能随机。您的操作系统具有基于加密随机生成器生成随机数据的方法。使用以下命令快速为Flask.secret_key(或SECRET_KEY)生成一个值:

     

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

     

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


加注

  

如您所见,Flask的创建者支持使用os.urandom()来构建Flask密钥的实践,从工具的较旧版本到最新版本。因此:为什么 @joshlsullivan的答案被否决(当当之选),为什么 @MikhailKashkin os.urandom()写道那是可怕的主意却是个谜。

答案 2 :(得分:0)

app = Flask(__name__)下方:app.secret_key = os.urandom(24)