Tips

sessionとcookie

Webアプリケーションを作る場合、sessionとcookieの概念は知っておく必要があります。

sessionの情報やcookieは主にユーザビリティを高めるために使われていますが、Flaskで使いたい場合はどうすれば良いのでしょうか?

ここではFlaskを使ったsession、cookieの使い方について解説します。

sessionとは?

まずはsessionから見ていきましょう。

sessionは一般には通信の開始から終了までを指す言葉ですが、WebアプリケーションではWebサービスに接続したタイミングでsessionが始まり、サーバーから切断した時(主にブラウザを閉じた時やWebサービスごとに設定されているタイムアウト時間を超過した時)にsessionが終了します。

sessionにはWebサービスにアクセスしているユーザーごとの情報を格納することができます。

sessionを使う

では実際にsessionを使ってどんなことができるのかを見ていきましょう。

今回はsessionを使ったカウンターを作成します。

送信ボタンを押すたびにカウントが1ずつ増えていきます。

from flask import Flask, render_template, session
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret_key'

@app.route('/counter')
def counter():
    if 'counter' in session:
        session['counter'] += 1
    else:
        session['counter'] = 0
    return render_template("session.html", count = session['counter'])

app.run(debug=True, host=os.getenv('APP_ADDRESS', 'localhost'), port=8001)



(session.html)
<!DOCTYPE html>
<html lang="ja">

<body>
  <form action='/counter'>
    <input type="submit">
  </form>
  <p>{{count}}</p>
</body>

</html>

sessionを使う上で必要なのはFlaskのsessionモジュールです。先にインポートしておきましょう。

次にapp.config['SECRET_KEY']で通信する際の暗号キーを設定します。今はsecret_keyを設定していますが、実運用で使う場合はランダムの文字を入力を推奨します。

設定は以上です。次に/counterにアクセスされたときの処理です。

やっていることは非常にシンプルで、counterというsessionデータがある場合は+1し、まだ設定されていない場合は0で初期化しています。

最後にsession.htmlにcounterの値を渡して終了です。

通常の変数であれば一連の処理が終了したタイミングで変数は破棄されてしまいますが、sessionに格納されている変数は通信が切断されるまではずっと残り続けるので、こういったカウンターを簡単に作成することができます。

なお、2つのブラウザを立ち上げて片方だけボタンを押すと、ボタンを押した側のブラウザのカウンターは増えますが、もう一方のカウンターは増えません。

これは各ブラウザごとにsessionが分かれているので、それぞれのsessionごとにカウンター変数が格納されているからです。

(左がchrome、右がSafari)

cookieとは?

次にcookieについて見ていきましょう。

cookieは「WebサービスがクライアントのPCやスマホに必要なデータを保存すること」です。

cookieを有効にしないでWebサイトを閲覧すると「cookieを有効にしていください」とメッセージが出ることがありますが、あれはWebサイトからユーザーの端末に必要なデータを保存させてください。というメッセージなんですね。

なぜデータを保存する必要があるのかというと、基本的にユーザーがWebサイトをより便利に活用できるようにするためです。

例えばcookieにログイン情報を保存しておくことで、次に同じWebサイトにアクセスしたときに自動でログインさせたりできます。

また、一度ショッピングカートに商品を入れたあとにログアウトし、再度ログインされたときに、ショッピングカートの中身をログアウト前と同じ状態にしておくのにもcookieが使われています。

cookieはデータの保存期間をWebサイト側が決められるので、sessionのようにデータが意図しないタイミングで消えてしまうことがありません。

cookieを使う

ではFlaskでcookieを実際に使ってみましょう。

今回は簡単な実験として「30秒間だけjsonの情報を格納しておく」処理を作ってみます。

実運用でcookieを使う場合はもっと長い期間(14日間とか)を設定することが多いですが、ここではcookieに値が格納されている状態と、cookieから値が自動的に削除される挙動をみてもらいたいので30秒にします。

「cookieを設定」ボタンを押すとcookieに値を設定します。

「戻る」を押すと元の画面に戻ります。

戻るとcookieの情報が画面に表示されます。

「更新」ボタンを押すと画面が更新されます。

30秒経ってから更新ボタンを押すと「cookieが設定されていません」と表示されます。

from flask import Flask, render_template, make_response, request
import os
import json
import datetime

app = Flask(__name__)

@app.route('/resp')
def resp():
    max_age = 30 #30秒
    expires = int(datetime.datetime.now().timestamp()) + max_age
    response = make_response(render_template("cookie.html"))
    user_info = {'id':'123', 'password':'user_password'} #cookieに格納するデータ
    response.set_cookie("user_info", value=json.dumps(user_info), expires=expires)
    return response

@app.route('/view')
def view():
    user_info = request.cookies.get('user_info')
    if user_info is not None:
        user_info = json.loads(user_info)
    return render_template('view.html', user_info = user_info)

app.run(debug=True, host=os.getenv('APP_ADDRESS', 'localhost'), port=8001)

(view.html)
<!DOCTYPE html>
<html lang="ja">

<body>
  <form>
    <input type="submit" value="cookieを設定" formaction="/resp">
    <input type="submit" value="更新" formaction="/view">
  </form>
  {% if user_info == None %}
    <p>cookieが設定されていません。</p>
  {% else %}
    <p>id:{{user_info.id}}</p>
    <p>password:{{user_info.password}}</p>
  {% endif %}
</body>

</html>

(cookie.html)
<!DOCTYPE html>
<html lang="ja">

<body>
  <p>cookieに値が格納されました。</p>
  <form action='/view'>
    <input type="submit" value="戻る">
  </form>
</body>

</html>

/respにアクセスされたときにcookieに値をセットし、/viewにアクセスされたときにcookieの設定値を画面に表示しています。

まず/respからみていきましょう。

expiresはcookieの寿命です。cookieがいつまで生き続けるのかをint型で指定します。

ここではdatetime.now()に30を追加しているので、設定した時点から30秒間だけ生き続けます。

次にmake_responseにcookie.htmlを渡し、レスポンスを作成します。make_responseは先にインポートしておきましょう。

user_infoがcookieに格納するデータです。

最後にresponse.set_cookieでデータを格納します。1つ目の引数がkeyになっていて、cookieからデータを取り出すときはこのkeyを指定して取り出します。

最後に作成したresponseを返して終了です。

次に/viewを見てみましょう。

初めにrequest.cookies.getでcookieに格納したデータを取得しています。先ほど指定したkeyを使っていますね。

cookieにデータを登録していない場合はデフォルトでNoneが返ってくるので、Noneでない場合のみjsonをパースしてview.htmlに渡しています。

これで完成です。cookieをセットして30秒後にちゃんとcookieが削除されているのを確認してみましょう。

タイトルとURLをコピーしました