会員登録すると
学習することができます。
会員登録する(無料)
登録済みの方はこちら
ログイン

セッションとトークン ― 有効期限と「止め方」を最初に決める

目安学習時間 13分

課題

全問正解でレクチャー完了です。

【問題1】

トークンの中に「管理者」という権限を書いて長い期限で発行した場合、後から困ることはどれですか。

[選択肢]

【問題2】

JWT について正しいものはどれですか。

[選択肢]
会員登録すると
学習することができます。
会員登録する(無料)

学ぶ目的

ログインの状態をどこに持つか

ログインしたあと、「この人はログイン済み」という状態をどこかに持つ必要があります。持ち方は大きく2つです。

持ち方 仕組み 途中で止めるには
サーバーに持つ ブラウザには意味の無いランダムな番号だけを渡し、中身はサーバーが覚える サーバーの記録を消せば、すぐ止まる
トークン自体に持つ 誰か・権限・期限をトークンの中に書き、署名で改ざんを防ぐ 期限が来るまで止まらない(止めるには別の仕組みが要る)

後者の代表が JWT(JSON Web Token)です。3つの部分(ヘッダー・中身・署名)を「.」でつないだ文字列です。なお、Rails の標準のセッションも、中身を暗号化して Cookie に入れる「自分で持つ」側の方式です。

JWT の中身は誰でも読める

手元で JWT を作り、中身の部分を Base64 から戻してみました(Ruby の jwt 3.2.0 で確認)。

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiIsInJvbGUiOiJtZW1iZXIiLCJleHAiOjE3OTMwMDAwMDB9.E8pvJJiZz6lE...
Base64.urlsafe_decode64("eyJzdWIiOiI0MiIsInJvbGUiOiJtZW1iZXIiLCJleHAiOjE3OTMwMDAwMDB9")
# => {"sub":"42","role":"member","exp":1793000000}

鍵が無くても読めました。署名は改ざんを見破るためのもので、中身を隠すものではありません。 中に個人情報や秘密を入れてはいけません。

一方、中身の role を書き換えると、検証で JWT::VerificationError になりました。期限(exp)を過ぎたものは JWT::ExpiredSignature です。改ざんと期限切れは、正しく検証すれば弾けます。

後から困ること

  • JWT を長い期間(たとえば30日)有効にする。 漏れたとき、退会させたいとき、期限が来るまで止められません。止めるために「無効にしたトークンの一覧」をサーバーに持つと、結局サーバーに状態を持つことになります
  • トークンに権限を書く。 管理者から外しても、手元のトークンには「管理者」と書いてあります。期限が来るまで、古い権限のまま動きます
  • ログアウトを「ブラウザの Cookie を消すだけ」にする。 盗まれた写しは、まだ生きています

最初に決める3つのこと

  1. 有効期限: 使うためのトークンは短く(数分〜1時間程度)、長く使いたいなら、作り直すための別のトークンを持たせる
  2. 失効の単位: 1つの端末だけ/その人の全部の端末/全員、のどれを止められる必要があるか
  3. ログアウトの意味: その端末だけか、全部の端末か

naminori の例

  • AIアプリとの接続(第5回)に渡すトークンは、中身を持たないランダムな文字列です。サーバーにはトークンそのものではなく照合用の値(ダイジェスト)だけを保存し、一覧から1件ずつ失効できます。使うためのトークンは短い期限で、作り直すためのトークンは使うたびに入れ替わり、古いものは使えなくなります
  • 会員がログアウトすると、「ブラウザを閉じてもログインしたままにする」ための印を、他の端末の分も含めて無効にします

このレクチャーで学ぶこと

  • ログインの状態をサーバーに持つか、トークンに持つか
  • JWT の中身は誰でも読める(手元で確認)
  • 長い期限・権限入りのトークンで後から困ること
  • 有効期限・失効の単位・ログアウトの意味を決める

質問

まだ質問は投稿されていません。

質問投稿

ログイン後に質問の投稿ができます。