JWTデバッガー
問題なさそうなトークンでの401は、ほぼいつも6つのうちのどれかです。このページはサーバーが読むとおりにトークンを見せ、どれなのかを教えます。
エンドポイントを試すために、自分でトークンに署名できます。計算はすべてこのページの中で行われます。
鍵も出来上がったトークンもブラウザーの中だけに残ります。どこにも送信されず、共有リンクにも含まれません。
このトークンを自分のコードで検証しましょう。サンプルはヘッダーのアルゴリズムに合わせて変わります。
拒否されているJSON Web Tokenを調べる
トークンの失敗の仕方は数えるほどで、しかもそのどれもトークンそのものには現れません。ドットで区切られた3つのBase64URLの塊にすぎないからです。ここに貼れば、議論できるものに変わります。ヘッダーの各項目とクレームが、何のためのものかを説明する表になり、有効期限は言葉に訳され、署名は手元の鍵で確かめられます。
入力しながらデコードされ、どこにも送信されません。こういうページでははっきり言うべきことです。これから貼り付けようとしているのは、誰かのアカウントで現に使える資格情報だからです。
6つの失敗、確かめる価値のある順に
| 何が起きたか | ここでの見え方 | 対処 |
|---|---|---|
| 期限切れ | ヘッダーの上の行が「期限切れになりました」と出る | トークンを取り直す。数秒差なら時計を確認する |
| オーディエンス違い | audが別のAPIを指している | APIが期待するオーディエンス向けにトークンを取得する |
| 発行者違い | issが本番ではなくステージングのURL | クライアントを正しい発行者へ、あるいはAPIの設定を直す |
| 鍵違い | 検証が「署名が一致しません」と言う | 発行者が署名に使った鍵を使う。Base64のシークレットに注意 |
| アルゴリズム違い | ヘッダーはES256、手元の鍵はRSA | 鍵欄の横に出ているアルゴリズムに鍵を合わせる |
| そもそもJWSでない | ページが5つの部分のJWEと呼ぶ | ペイロードは暗号化済み。復号鍵のある場所で読む |
順番が大事です。有効期限とオーディエンスは鍵も他人の協力も要らず、数秒で片付きます。逆に、結局はaudの食い違いだった署名の問題を追いかけると、午後がまるごと消えます。
読むことと検証することは違う
ここで多くの人がつまずきます。デコードして分かるのは、トークンが何を主張しているかだけです。それが本当かどうかは何も言いません。ヘッダーとペイロードは暗号化ではなくエンコードで、誰でも自分で書けるからです。検証とは、発行者のシークレットか公開鍵で署名を計算し直すこと——このページがブラウザー内で行うこと——であり、主張を事実に変える唯一の手順です。
ですからデコード結果は仮説を立てるために使い、検証ボタンでそれを試してください。そして自分のコードでは、デコードした内容の上に認可の判断を置かないことです。「コード」タブがサーバー側の検査を8つの言語で示すのは、まさにそのためです。エンコードそのものが引っかかるなら、Base64とBase64URLの違いが、JWTの一部をふつうのBase64デコーダーにそのまま貼れない理由を説明しています。
トークンの問題に見えて、そうではないもの
- トークンと一緒にコピーされた
Bearerという語や、端末から来た改行。どちらも署名対象の入力を変え、署名を壊します。 - ログビューアーに切り詰められたトークン。署名部分はアルゴリズムごとに長さが決まっているので、切れていれば必ず失敗します。
- シークレットを共有する2つのサービスの一方が、それをBase64で保存している場合。シークレットは Base64 にチェックを入れるとその側を再現できます。
- 発行者が鍵を入れ替えたために、もう存在しない
kid。トークンは正しく、古いのは鍵セットのほうです。
トークン自体の疑いが晴れたら、残る容疑者はサーバー側です。まったく検証しないミドルウェア、ずれていく時計、古い鍵セットを抱えたキャッシュ。そうしたものを試すのに、状態の分かったトークン——期限切れ、有効、自分の鍵で署名したもの——が必要なら、JWTジェネレーターが作ってくれますし、有効期限チェッカーが検証側の時刻クレームの読み方を説明しています。