【入門編】 アクセストークンとリフレッシュトークンの有効期限設計 – Web APIアーキテクチャ・データ連携実践ガイド

「鍵」を渡す怖さを知っていますか?——アクセストークンとリフレッシュトークンで守るWeb APIの安全

こんにちは。ネットワークの深淵を愛するエンジニアの皆さん、今日も元気にパケットを追いかけていますか?

Web APIを作っていると、必ずぶつかる壁があります。それは「どうやってユーザーの本人確認をし続けるか」という問題です。一度ログインしたら、ページを移動するたびにパスワードを打たせたくはありませんよね。そこで登場するのが「トークン」という名の「通行手形」です。

今回は、この通行手形を安全に扱うためのベストプラクティス、「アクセストークン」と「リフレッシュトークン」の使い分けについて、現実世界の例を交えて紐解いていきましょう。

—

「一生使える通行手形」が一番危ない理由

まず、想像してみてください。あなたが高級ホテルのオーナーだとします。お客様に「部屋に入るための鍵」を渡す際、もしその鍵が「一度渡したら、お客様がチェックアウトするまで永久に使えるマスターキー」だったらどうでしょう?

もし、その鍵を廊下で落としてしまったら……。誰かがその鍵を拾えば、滞在中ずっと好き勝手に部屋へ出入りできてしまいますよね。これこそが、Web APIにおいて「有効期限のないトークン」を使ってはいけない理由です。

そこで、私たちは「短命な鍵」と「予備の鍵」を組み合わせて使うことにしました。

—

2つの鍵:アクセストークンとリフレッシュトークン

Web APIの世界では、以下の2種類の鍵(トークン)を使い分けるのが鉄則です。

1. アクセストークン(短命な鍵)

  • 役割: APIにリクエストを送る際の「通行手形」。
  • 寿命: 数分〜1時間程度と極めて短い。
  • たとえ: 「今日の日付が入った1日限りの入館証」。

2. リフレッシュトークン(長命な鍵)

  • 役割: アクセストークンが切れたときに、新しいアクセストークンを再発行するための「引換券」。
  • 寿命: 数日〜数週間と比較的長い。
  • たとえ: 「本人確認書類を提示して、新しい入館証をもらうための引換券」。

なぜこの組み合わせが最強なのか?

アクセストークンの寿命を短くしておけば、万が一誰かに盗まれても、すぐに無効化されます。盗んだ犯人は「あれ、さっきまで使えたのに!」と数十分で締め出されるわけです。一方で、リフレッシュトークンは厳重に保管しておけば、ユーザーは毎回ログインし直す手間から解放されます。

—

実装のイメージ:Python(Flask)でのトークン発行フロー

実際にコードで見てみると、イメージが湧きやすいはずです。あくまで概念的なコードですが、やり取りの流れを見てみましょう。

# ユーザーがログインした時に発行するイメージ
def login(username, password):
    if authenticate(username, password):
        # 短命なアクセストークン(例: 15分で期限切れ)
        access_token = generate_token(user_id, expires_in=900)
        
        # 長命なリフレッシュトークン(例: 7日間有効)
        refresh_token = generate_token(user_id, expires_in=604800)
        
        # クライアントへ返す(リフレッシュトークンはHttpOnlyクッキーに入れるのが安全!)
        return {
            "access_token": access_token,
            "refresh_token": refresh_token
        }

ここで重要なのが、「リフレッシュトークンは、JavaScriptから直接触れない(HttpOnly属性を付けた)クッキーに入れる」という点です。こうすることで、万が一ブラウザに悪意のあるスクリプト(XSS攻撃など)が仕込まれても、犯人がリフレッシュトークンを盗み出すハードルが格段に上がります。

—

運用時のチェックポイント:もしも盗まれたら?

ネットワークの現場では、「想定外の事態」が必ず起きます。もしリフレッシュトークンさえも盗まれてしまったらどうするか。

ここで有効なのが「リフレッシュトークン・ローテーション」という手法です。

1. 新しいアクセストークンを発行するとき、「あわせて新しいリフレッシュトークンも一緒に発行する」。
2. 古いリフレッシュトークンは、使った瞬間に「無効」にする。

もし犯人が古いリフレッシュトークンを使い、同時に正当なユーザーが新しいリフレッシュトークンを使ってしまったら?システム側は「おや、同じ鍵が二箇所で使われているぞ。これは不正アクセスの予兆だ!」と検知し、そのユーザーの全セッションを強制終了させることができるのです。

—

まとめ:安全は「手間」と「制約」から生まれる

APIの設計において、「便利さ」を追求しすぎると、セキュリティという大切な土台が揺らぎます。

  • アクセストークンは短く。
  • リフレッシュトークンは厳重に管理。
  • ローテーションで不正の芽を摘む。

最初は少し面倒に感じるかもしれませんが、これこそがユーザーの信頼を守るための「ネットワークエンジニアの作法」です。

皆さんの作るAPIが、今日も安全に、軽快にパケットを届けてくれることを願っています。もしトラブルが起きたら、パケットを眺めて「このトークンは今、どの期限の中にいるんだ?」と冷静に分析してみてください。きっと答えは見つかるはずです。

それでは、また次回の深淵でお会いしましょう!

コメント

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