web-dev-qa-db-ja.com

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を保存できないのはなぜですか?

30
sedavidw

Flaskセッションのドキュメント によると:

...これは、署名に使用される秘密鍵を知らない限り、ユーザーがCookieの内容を見ることができるが、それを変更できないことを意味します。

セッションを使用するには、秘密鍵を設定する必要があります

秘密鍵を設定します。そして、intではなくstringを返すべきです。

#!/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()
50
falsetru

@ falsetruで述べたように、秘密鍵を設定する必要があります。

session Cookieをユーザーのブラウザに送信する前に、FlaskはCookieに暗号的に署名します。これは、Cookieをデコードできないという意味ではありません。Flaskは署名されたCookieを追跡するため、リクエスト(リクエストヘッダー)とともに送信されたCookieが有効なCookieかどうかを判断するために、独自の「マジック」を実行できます。

使用できるいくつかのメソッドは、すべてFlaskクラスインスタンスに関連し、一般にappとして定義されます:

  • appオブジェクトの_secret_key_変数の定義

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

次に例を示します( この記事 からの適応)。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 -
_

上記の例では、Flaskの秘密鍵を生成するために、os libとurandom()関数を使用していることに気付いたかもしれませんね。

公式ドキュメント から:

適切な秘密鍵を生成する方法

秘密鍵はできるだけランダムにする必要があります。オペレーティングシステムには、暗号化ランダムジェネレーターに基づいてかなりランダムなデータを生成する方法があります。次のコマンドを使用して、Flask.secret_key(またはSECRET_KEY)の値をすばやく生成します。

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

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


プラス注

ご覧のように、Flask=の作成者は、古いバージョンのFlask秘密鍵を構築するためのos.urandom()の使用をサポートしています。ツールを最新バージョンに変更します。そのため、なぜ@ joshlsullivanの回答は、ダウン票を受け取った(アップ票に値する)およびなぜ@ MikhailKashkinは、os.urandom()を使用するのはひどい考えであり、謎だと書いています。

1
ivanleoncz

app = Flask(__name__)の下にapp.secret_key = os.urandom(24)を配置します。

0
joshlsullivan