FlaskとJWTの連携をさらに強化!初心者でもわかる実践的な活用例とセキュリティ設計
生徒
「先生、Flaskでログイン機能を作ったときに、JWTっていうのを使うと便利って聞いたんですけど、それって何ですか?」
先生
「JWTは『JSON Web Token(ジェイソン・ウェブ・トークン)』の略で、ユーザーの認証情報を安全にやり取りするための仕組みなんです。最近のWebアプリやAPIでとてもよく使われていますよ。」
生徒
「Flaskでも使えるんですか?難しそうに聞こえますけど…」
先生
「Flaskでも簡単に使えます!今日はFlaskとJWTを連携させて、より実践的な使い方をわかりやすく解説していきましょう。」
1. JWT(JSON Web Token)とは?
JWT(ジェイソン・ウェブ・トークン)は、ユーザーのログイン状態を安全に保持するための「デジタルなカギ」のようなものです。たとえば、あなたがWebアプリにログインすると、その情報をサーバーが「署名付きのトークン」にして発行します。このトークンをブラウザやアプリ側に保存し、次のアクセス時に一緒に送ることで、「この人はログイン済みです」と確認できます。
JWTは3つの部分からできています。
- ヘッダー(Header):どんな方式で暗号化しているかを示す部分
- ペイロード(Payload):ユーザー情報などのデータ部分
- 署名(Signature):データ改ざんを防ぐためのチェック部分
この3つを組み合わせた文字列をトークンとして使います。例えばこんな形です。
xxxxx.yyyyy.zzzzz
2. FlaskでJWTを使うための準備
FlaskでJWTを使うには、「Flask-JWT-Extended」というライブラリを使うのが便利です。ターミナルで次のようにインストールします。
pip install Flask-JWT-Extended
これで、JWTを使って認証やトークンの検証ができるようになります。
3. 基本的なログインとトークン発行の仕組み
まずはログイン時にトークンを発行する基本的な例を見てみましょう。
from flask import Flask, jsonify, request
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
app = Flask(__name__)
app.config["JWT_SECRET_KEY"] = "super-secret-key"
jwt = JWTManager(app)
# 仮のユーザー情報
users = {"admin": "1234", "user": "abcd"}
@app.route("/login", methods=["POST"])
def login():
username = request.json.get("username")
password = request.json.get("password")
if username in users and users[username] == password:
token = create_access_token(identity=username)
return jsonify(access_token=token)
return jsonify({"msg": "認証失敗"}), 401
@app.route("/protected", methods=["GET"])
@jwt_required()
def protected():
current_user = get_jwt_identity()
return jsonify(message=f"{current_user}さん、保護されたページへようこそ!")
if __name__ == "__main__":
app.run(debug=True)
このコードでは、/loginに正しいユーザー情報を送ると、JWTトークンが発行されます。そして/protectedにアクセスする際に、そのトークンをヘッダーに含めて送信すると、認証されたユーザーだけが閲覧できます。
4. トークンの有効期限とリフレッシュ機能を追加する
トークンには有効期限を設けるのが一般的です。これを設定することで、期限切れのトークンを防ぎ、セキュリティを高められます。
from datetime import timedelta
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(minutes=5)
これで、発行されたトークンは5分後に無効になります。さらに、リフレッシュトークンを発行して、古いトークンが切れても新しいトークンを取得できるようにできます。
from flask_jwt_extended import create_refresh_token, jwt_refresh_token_required
@app.route("/refresh", methods=["POST"])
@jwt_refresh_token_required
def refresh():
current_user = get_jwt_identity()
new_token = create_access_token(identity=current_user)
return jsonify(access_token=new_token)
これで、一定時間ごとにトークンを更新しながら安全なログイン状態を保てます。
5. ロール(権限)をJWTに含める実践例
JWTのペイロード部分にユーザーのロール(権限)を含めることで、アクセス制御も可能です。
@app.route("/admin", methods=["GET"])
@jwt_required()
def admin_only():
current_user = get_jwt_identity()
if current_user != "admin":
return jsonify(msg="このページは管理者のみがアクセスできます"), 403
return jsonify(msg="管理者ページへようこそ!")
このように、トークンに含まれるユーザー情報を使ってページごとの制御を行うことで、Flaskの認可(アクセス許可)機能を強化できます。
6. 実践的なJWT活用パターン
実際のWebアプリケーションでは、次のような設計パターンがよく使われます。
- ① APIベース認証: ReactやVueなどのフロントエンドからJWTを使ってログインする方式
- ② モバイルアプリとの連携: スマホアプリがサーバーAPIにアクセスするときも同じトークンを利用
- ③ サードパーティ連携: 外部サービスと安全にデータをやり取りする際の認証トークンとして使用
これらを実装することで、セッションを使わずにスケーラブル(拡張しやすい)なアプリ設計が可能になります。
7. JWTを安全に使うための注意点
JWTは非常に便利ですが、使い方を誤るとセキュリティリスクがあります。安全に使うためのポイントを覚えておきましょう。
- ・秘密鍵(secret key)を絶対に漏らさない:トークンを偽造される恐れがあります。
- ・HTTPS通信を使う:平文通信だとトークンが盗まれる危険があります。
- ・短い有効期限を設定する:長期間のトークンは危険です。
- ・リフレッシュトークンを併用する:セキュリティと利便性を両立できます。
FlaskとJWTを正しく組み合わせることで、安全で信頼性の高いWeb認証システムを構築できます。