カテゴリ: Flask 更新日: 2025/12/24

Flaskでリフレッシュトークンを管理する方法まとめ|初心者でもわかる安全なトークン更新の仕組み

Flaskでリフレッシュトークンを管理する方法まとめ
Flaskでリフレッシュトークンを管理する方法まとめ

先生と生徒の会話形式で理解しよう

生徒

「先生、Flaskでログインするときにトークンを使うって聞いたんですけど、リフレッシュトークンっていうのもあるんですか?」

先生

「そうですね。Flaskでログイン機能を作るときに使うJWTトークンには、通常のアクセス用トークンとリフレッシュトークンの2種類があります。リフレッシュトークンは、期限切れになったトークンを再発行するために使うんです。」

生徒

「へえ!じゃあ、アクセス用トークンが切れてもログインし直さなくていいんですね?」

先生

「その通りです!今日はFlaskでリフレッシュトークンを安全に管理する方法を、一つひとつ丁寧に見ていきましょう。」

1. そもそもリフレッシュトークンとは?

1. そもそもリフレッシュトークンとは?
1. そもそもリフレッシュトークンとは?

リフレッシュトークン(Refresh Token)とは、アクセス用トークンが期限切れになったときに、新しいトークンを発行するための特別な鍵のようなものです。ログインし直すことなく、再認証をスムーズに行えるようにする仕組みです。

例えば、あなたがWebアプリにログインしていて、5分でトークンが切れる設定だとしましょう。そのたびに再ログインするのは面倒ですよね。そこでリフレッシュトークンを使えば、裏で新しいトークンを発行してくれるので、ユーザーは快適に使い続けられます。

2. FlaskでJWTとリフレッシュトークンを使う準備

2. FlaskでJWTとリフレッシュトークンを使う準備
2. FlaskでJWTとリフレッシュトークンを使う準備

Flaskでリフレッシュトークンを扱うには、Flask-JWT-Extendedという拡張機能を使うのが便利です。インストールはとても簡単です。


    pip install Flask-JWT-Extended

このライブラリを使うと、ログイン時にアクセス用トークンとリフレッシュトークンを同時に発行したり、トークンを安全に検証する機能が使えます。

3. Flaskでリフレッシュトークンを発行する方法

3. Flaskでリフレッシュトークンを発行する方法
3. Flaskでリフレッシュトークンを発行する方法

次のサンプルコードでは、ログイン時に「アクセス用トークン」と「リフレッシュトークン」を同時に返すようにしています。


from flask import Flask, jsonify, request
from flask_jwt_extended import (
    JWTManager, create_access_token, create_refresh_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:
        access_token = create_access_token(identity=username)
        refresh_token = create_refresh_token(identity=username)
        return jsonify(access_token=access_token, refresh_token=refresh_token)
    return jsonify(msg="認証失敗"), 401

このようにしておくと、ログイン時に2つのトークンが発行されます。

  • access_token: 実際にAPIアクセスを許可するための短期間トークン
  • refresh_token: 新しいaccess_tokenを発行するための長期間トークン

4. リフレッシュトークンを使って新しいトークンを発行する

4. リフレッシュトークンを使って新しいトークンを発行する
4. リフレッシュトークンを使って新しいトークンを発行する

次に、期限切れになったトークンを更新するAPIを作ってみましょう。


@app.route("/refresh", methods=["POST"])
@jwt_required(refresh=True)
def refresh():
    current_user = get_jwt_identity()
    new_token = create_access_token(identity=current_user)
    return jsonify(access_token=new_token)

@jwt_required(refresh=True)と書くことで、「リフレッシュトークンが必要なルート」であることを指定できます。これにより、アクセス用トークンではアクセスできず、正しいリフレッシュトークンを持つユーザーだけが新しいトークンを受け取れます。

5. トークンの有効期限を設定する

5. トークンの有効期限を設定する
5. トークンの有効期限を設定する

セキュリティの観点から、トークンには有効期限を設定するのが一般的です。Flaskでは次のように設定できます。


from datetime import timedelta

app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(minutes=5)
app.config["JWT_REFRESH_TOKEN_EXPIRES"] = timedelta(days=30)

この設定では、アクセス用トークンは5分で切れ、リフレッシュトークンは30日間有効になります。これにより、セキュリティと利便性のバランスを保てます。

6. リフレッシュトークンの安全な管理方法

6. リフレッシュトークンの安全な管理方法
6. リフレッシュトークンの安全な管理方法

リフレッシュトークンは長期間有効なため、特に安全に扱う必要があります。以下の方法で管理するのがおすすめです。

  • ① データベースに保存する: ユーザーごとのトークンをデータベースに保存し、不正利用を検知したら削除できるようにします。
  • ② ブラウザのCookieに安全に保存する: HttpOnly 属性を使うことで、JavaScriptからアクセスできないようにします。
  • ③ HTTPS通信を使う: トークンが盗まれないように、常にSSLを有効にしましょう。

from flask import make_response

@app.route("/login_secure", methods=["POST"])
def login_secure():
    username = request.json.get("username")
    password = request.json.get("password")

    if username in users and users[username] == password:
        access_token = create_access_token(identity=username)
        refresh_token = create_refresh_token(identity=username)
        response = make_response(jsonify(access_token=access_token))
        response.set_cookie("refresh_token", refresh_token, httponly=True, secure=True)
        return response
    return jsonify(msg="認証失敗"), 401

このようにしておけば、リフレッシュトークンはCookieに安全に保存され、JavaScript経由で盗まれる心配が少なくなります。

7. 不正なトークンを無効化する仕組み

7. 不正なトークンを無効化する仕組み
7. 不正なトークンを無効化する仕組み

もし誰かにトークンを盗まれてしまった場合、そのトークンを「無効化」できる仕組みを作っておくと安心です。Flask-JWT-Extendedには、ブラックリスト(無効トークン一覧)を管理する仕組みを追加することもできます。


app.config["JWT_BLACKLIST_ENABLED"] = True
app.config["JWT_BLACKLIST_TOKEN_CHECKS"] = ["access", "refresh"]

blacklist = set()

@jwt.token_in_blocklist_loader
def check_if_token_revoked(jwt_header, jwt_payload):
    return jwt_payload["jti"] in blacklist

こうしておくことで、盗まれたトークンやログアウト時に無効化したトークンを簡単にブロックできます。

8. 実践で役立つリフレッシュトークンの設計ポイント

8. 実践で役立つリフレッシュトークンの設計ポイント
8. 実践で役立つリフレッシュトークンの設計ポイント

最後に、実際の開発でリフレッシュトークンを運用する際のポイントをまとめます。

  • ・リフレッシュトークンは短期間ごとに更新して、新しいものと入れ替える
  • ・ログアウト時に必ずトークンをブラックリストに登録する
  • ・トークンをログファイルに出力しない(漏洩リスクあり)
  • ・APIアクセスには常にHTTPSを使用する

これらの対策を行うことで、Flaskアプリケーションでも安全にリフレッシュトークンを活用できます。

カテゴリの一覧へ
新着記事
New1
Django
Djangoプロジェクトのディレクトリ構造を完全解説!初心者でも迷わないフォルダの見方
New2
Flask
Flask×Flask-SocketIOでチャットアプリを作る流れを初心者向けにやさしく解説
New3
Flask
Flaskアプリの作り方を基礎から学ぼう!初心者が覚えるべき開発の流れとは?
New4
Flask
Flask-WTFでファイルアップロードフォームを完全ガイド!初心者でもわかる画像やPDFのアップロード方法
人気記事
No.1
Java&Spring記事人気No1
Django
Django環境構築の全手順を完全解説!初心者でも迷わないPython・Djangoセットアップガイド
No.2
Java&Spring記事人気No2
Flask
Flask-Loginでユーザー認証を完全ガイド!初心者でもわかるログイン処理の作り方
No.3
Java&Spring記事人気No3
Python
Pythonの文字列を1文字ずつ処理する方法!for文やlist化の活用例
No.4
Java&Spring記事人気No4
Python
PythonでHello Worldを表示するには?初心者向けに最初の1行を実行してみよう
No.5
Java&Spring記事人気No5
Python
Pythonで定数を定義する方法!変更されない変数の書き方と命名ルールを初心者向けに解説
No.6
Java&Spring記事人気No6
Python
Pythonでリストを文字列に変換する方法を完全ガイド!初心者でもわかるjoinの使い方
No.7
Java&Spring記事人気No7
Flask
FlaskアプリをNginx + Gunicornで本番運用する方法!初心者でもわかるデプロイ構成の基本
No.8
Java&Spring記事人気No8
Python
Pythonのmatch文(パターンマッチング)とは?switch文の代替としての使い方をやさしく解説