この記事では、Flaskのセッションについて紹介します。
Flaskではwebアプリとユーザを紐づけるためにセッションと呼ばれる技術を使います。
セッションを使うことで、ユーザ(クライアント)を識別することができます。
クライアントを識別することで、Amazonなどのサイトでカートにアイテムを保存しておくことも可能になります。
セッション管理を使ってログイン、ログアウト機能を持つ認証ページを作ってみたいと思います。
目次
作ってみるサイト
作成するページは以下の通り。
- ログインページ
フォームを使ってIDとパスワードを入力させます。

- Indexページ(ログイン後に遷移するページ)
ログインが成功したユーザ名を表示します。

仕様としては以下の通り。
- セッションに保存するのは、ユーザIDとログイン状態(True,False)
- indexページで、ログイン状態を確認しログイン済みであればユーザIDを表示する
- 登録されていないユーザであればパスワードと共にセッションに保存しindexページへ移動(ユーザ登録(Sign Up)の役割をログインページでやってしまう)
- ユーザIDとパスワードの組み合わせは辞書で管理する
- ユーザIDに対するパスワードが違えば、パスワードが間違っているメッセージを表示する
- ログアウトページで、セッションの値を全て削除
実装のポイントは、IDとPWはPOSTされてきたの時の処理ですね。
少し処理が長くなりますが、以下のような判定をするコードを書いていきます。
- 辞書内にIDがある場合
- PWの値を照合
- PWが合っていればログイン済みにする
- PWの値が合っていなければログイン済みにしない
- PWの値を照合
- 辞書内にIDが無い場合
- IDとPWを新たに登録
- ログイン済みにする
- セッションにIDを保存
- ログイン済みであれば、indexページにリダイレクト
- ログイン済みで無ければ、PWが違うメッセージを表示する
ということで、以上を実装すると以下のコードになります。
コード
app.py
from flask import Flask, render_template, session, request, redirect app = Flask(__name__) app.secret_key = "aaa" user_data = {} @app.route("/", methods=["GET"]) def index(): if "flag" in session and session["flag"]: msg = "hello,"+str(session["uid"]) return render_template("index.html", title="ログイン後の画面です", message=msg) else: return redirect("/login") @app.route('/login', methods=['GET']) def login(): return render_template("login.html", title="ログインページ", message="以下のフォームからログインしてね") @app.route('/login', methods=['POST']) def login_post(): uid = request.form["uid"] pwd = request.form["pwd"] #ユーザが登録済みであった場合 if uid in user_data: # IDとパスワードの組み合わせが合っていれば、ログイン済みにする if user_data[uid] == pwd: session["flag"] = True # ログイン済みにしない else: session["flag"] = False #ユーザが登録していなかった場合、登録してログイン済みにする else: user_data[uid] = pwd session["flag"] = True session["uid"] = uid if session["flag"]: return redirect("/") else: return render_template("login.html", title="ログインページ", message="パスワードが違います") @app.route('/logout') def logout(): session.pop('uid', None) session.pop("flag", None) return redirect("/")
コードの簡単な解説
セッション情報の暗号化
セッションの情報は盗まれるとなりすましができてしまうため、秘密鍵を使って暗号化しています。`app.secret_key`というやつ。この値は何にしてもコードは動くが、もちろんバレないような乱数値の方が良い。
セッション情報の削除
session.popでは、セッションに保存された値を削除する。第二引数には、すでになかった場合に返す値を指定するがNoneを指定しておけば間違いない。
ログイン判定
indexページで、ログイン判定はどのようにやっているのでしょうか。
以下の2つの条件の確認を行っています。
- sessionにflagという名前のキーが存在するか
- flagがTrueであるか
2の条件で良いような気もしますが、なぜ1をチェックするのでしょうか。
セッション管理をする変数sessionはPythonの辞書と同じ性質を持ちます。
辞書ではキーが存在しないとエラーが発生します。辞書のキーが常に存在すれば必要ありませんが、今回の場合はログアウト機能のなかでキーの削除を行っています。
このような作りの場合には、辞書の値(value)の確認の前に、そもそもキーが存在するかどうかの確認も必要になってくるわけです。
参考
https://qiita.com/ikaro1192/items/d890eefbdbbfe1460252