音楽フェスの入口でチケットを確認されると、手首にリストバンドを巻いてもらえます。あとは会場のどこへ移動しても、リストバンドを見せるだけで通れる。いちいちチケットを出し直す必要はありません。
トークンは、ログインや認証が済んだことを示す小さなデータで、以降のやり取りで「この人は確認済みです」という証明に使うものです。ページを移動したり API を呼び出したりするたびにパスワードを送るのは手間がかかるうえに危険です。そこで一度ログインしたら証明を発行し、あとはそれを添えてやり取りします。Web アプリのログインのほか、スマホアプリとサーバーのやり取り、複数のサービスをまたいでログイン状態を保つシングルサインオン、外部サービスに自分の代わりに操作させる OAuth などで広く使われています。
ログインから期限切れまで
- ID とパスワードでログインする
- サーバーがトークンを発行して渡す
- 以降のリクエストには、パスワードの代わりにトークンを添えて送る
- サーバーはトークンを確かめて「ログイン済み」と判断する
- 有効期限が切れたら、もう一度ログインして新しいトークンをもらう
リストバンドに有効期限があるのと同じで、トークンにも期限があります。方式によって中身や期限の扱いは違うので、「トークンを使っているから安全」とは言えません。JWT のような標準的な形式を使うと、実装のミスを減らしやすくなります。
盗まれたリストバンドは誰の腕でも通れる
リストバンドを見た係員は、巻いているのが本人かどうかまでは確かめません。トークンも同じで、漏れてしまえば、手に入れた人がそのまま本人として振る舞えます。
だから、トークンは短い命にしておきます。有効期限を長くしすぎない。盗まれたと分かったらすぐに無効にできる仕組みを持つ。通信は HTTPS で暗号化して、途中で盗み見られないようにする。この3つをセットで設計します。
セッションや API キーとはどう違う?
セッションは、ログイン状態をサーバー側の記録で管理する仕組みです。トークンは状態をデータとして利用者側に持たせるので、方式によってはサーバーが記録を調べなくても検証できます。
APIキーは、利用者やアプリを見分けるための固定の文字列です。トークンはログインの操作を経て発行され、有効期限や権限の情報を持つ点が違います。
トークンの保存場所としてクッキーが使われることも多く、これらは対立するものではなく、組み合わせて使われています。