简体   繁体   English

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

[英]Internal Server Error when using Flask session

I want to save an ID between requests, using Flask session cookie, but I'm getting an Internal Server Error as result, when I perform a request. 我想使用Flask session cookie在请求之间保存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 session cookie with the following value when I perform the request? 为什么我在执行请求时无法使用以下值存储session cookie?

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. ...这意味着用户可以查看cookie的内容但不能修改它,除非他们知道用于签名的密钥。

In order to use sessions you have to set a secret key . 要使用会话,您必须设置密钥

Set secret key . 设置密钥 And you should return string, not int. 你应该返回字符串,而不是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()

As @falsetru mentioned, you have to set a secret key. 正如@falsetru所提到的,你必须设置一个密钥。

Before sending the session cookie to the user's browser, Flask signs the cookies cryptographically, and that doesn't mean that you cannot decode the cookie. 在发送之前session cookie发送到用户的浏览器,瓶签饼干加密,而这并不意味着你不能解码的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. 我认为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_key variable for app object app对象定义secret_key变量

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

     app.config['SECRET_KEY'] = b'6hc/_gsh,./;2ZZx3c6_s,1//' 
  • using an external configuration file for the entire Flask application 使用外部配置文件来处理整个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 session cookie, considering the participation of both Client and Server sides: 以下是一个示例( 本文的改编),重点是提供更清晰的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()

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 os lib and the urandom() function, in order to generate Flask's secret key, right? 您可能已经注意到,在上面的示例中,我使用的是os lib和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): 使用以下命令快速生成Flask.secret_key(或SECRET_KEY)的值:

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

b'_5#y2L"F4Q8z\\n\\xec]/' 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. 正如您所看到的,Flask的创建者支持使用os.urandom()来构建Flask密钥,从旧版本的工具到最新版本。 So: why @joshlsullivan's answer received downvotes (deserves an upvote) and why @MikhailKashkin writes that, using os.urandom() is terrible idea, are mysteries. 那么:为什么@ joshlsullivan的回答得到了downvotes(值得一个upvote)以及为什么@MikhailKashkin写道,使用os.urandom()是一个可怕的想法,是神秘的。

app = Flask(__name__)放置: app.secret_key = os.urandom(24)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM