JWT整理
JWT自体は、json風味の文字列。
3つのコンポーネントを . でくっつける
- ヘッダー
- トークンのタイプと署名アルゴリズム
- ペイロード
- ユーザー情報(トークン発行者)、有効期限など
- 署名
- 改ざんがないことを確認
JWTの使い道
どうもいろんな使い方があるので分かりにくい。ページにより説明の仕方がちょっと違う。
- 認証(Authentication)
- ログイン方法その1
- クライアントは、ID/パスを送信し、JWTを受け取る
- ログイン方法その2
- クライアントは、ID/パス等をJWTに変えて送信し、認証成否を受け取る
- ログイン方法その1
- 認可: アクセス許可(Authorization)
- APIリクエスト
- クライアントはJWTを送る
- APIリクエスト
フロントでトークンを LoacakStorage に保存しておく話
JWT、token、トークンと3種類の言葉が出てくるので分かりにくいなあ。
認証におけるJWTの利用
【JWT】 入門 - Qiita
JWTとは公式サイトJSON Web Tokenの略 電子署名により、改ざん検知できる。認証用のトークンなどで用いられる。構成ヘッダ、ペイロード、署名の3つから成る。それぞれは、Ba…
- ログイン(または新規登録)より、ユーザはJWT(JSON Web Token ジョット)を取得する。
- JWTを付与してAPIにリクエストを行う。
ログインの話
説明方法1: ログイン(ユーザー確認)
【JWT】 入門 - Qiita
JWTとは公式サイトJSON Web Tokenの略 電子署名により、改ざん検知できる。認証用のトークンなどで用いられる。構成ヘッダ、ペイロード、署名の3つから成る。それぞれは、Ba…
- クライアントは、ユーザー名とパスワードを入力の上、ログインAPIにリクエストを送る
- サーバーは、正しいユーザー情報であるなら、ユーザーIDと秘密鍵よりトークンを生成する
- サーバーは、トークンをクライアントに返す(レスポンス)
説明方法2: OAuth認証(アクセストークンの発行)
- クライアントは、認証サーバーにユーザー名とパスワードを送信し、アクセストークンを要求する
- 認証サーバーは、ユーザー認証を行う
- 認証が成功したら、認証サーバーは、期限付きのアクセストークンを生成する
- 認証サーバーは、アクセストークンをクライアントに返す(レスポンス)
APIリクエストの話
説明: Bearer認証方式でAPIリクエスト(やりたい事)
- クライアントは、上記で取得したトークンをAuthorizationヘッダにセットし、決められたメソッド(GET,POST等)と入力情報でリクエストを送る
- サーバーは、秘密鍵を用いてトークンを検証する
- 認証が失敗した場合、サーバーは401 Unauthorizedを返す
- サーバーは、入力情報から返すべき出力情報を整える
- サーバーは、クライアントに出力情報を返す
Authorization Bearerヘッダ
クライアントがサーバーにトークンを送る方法は、大きく言って、
- (1)ヘッダーに含める方法【推奨】
- リクエストボディやURLクエリが汚れない
- (2)リクエストボディに含める方法
- (3)URLクエリに含める方法
がある。
Authorization: Bearerヘッダーの送信
- 送信するヘッダ :
Authorization: Bearer トークン
- トークンは token68 文字列を指定する
- 改行のない base64 文字列は正しい token68 文字列である
ちなみにBasic認証では Authorization: Basic というヘッダーを用いるよ。
エラーの場合のレスポンス 401 Unauthorized
理由1: Authorization ヘッダーなしのアクセス
WWW-Authenticate
ヘッダに realm
パラメータをつけて返す。
理由2: トークンが正しくない
期限切れとか。
WWW-Authenticate
ヘッダにrealm
パラメータと error
パラメータ(error=”invalid_token”,
error_description=”The access token expired”)をつけて返す。
別の説明みっけ: JWT認証
JWTトークン生成とJWTトークン検証の仕組みが書いてある。
JWTトークン生成
- フロントは、ユーザー・パスワードを送信
- バックエンドは、それが正しいか検証したうえで、
- (1)payloadを作成(ユーザーIDなどを含める。パスワード含めない)
- (2)ヘッダーにアルゴリズム種類を入れる
- payloadとヘッダーをBase64エンコードする
- (3)それを秘密鍵でハッシュ化し署名
- JWTトークンは、(1).(2).(3) の形
むむ、フロントはそのJWTトークンをそのまま保持していればいいのかな
JWTトークン検証
- フロントは、JWTトークンを送信(Authorization ヘッダーに入れて)
- バックエンドは、JWTトークンを . で3分割する(ヘッダー、payload、署名)
- JWTトークンのヘッダー内のアルゴリズムとpayload内のユーザー情報と秘密鍵から署名を作り、JWTトークンの署名と比較する
- 署名が一致すれば、認証成功
秘密鍵
秘密鍵は、バックエンドのみが持つ。
秘密鍵が長ければ、JWTトークンの第1・第2フィールドから同じ署名(第3フィールド)を作ることは出来ないはず。秘密鍵は 256bit (32バイト) 以上を推奨。
再度、整理
フロントは、秘密鍵を持たず、JWTを LocalStorage に保持する。
- フロントは、
- JWTトークンがLocalStorageにあり、
- 有効期限内なら、
- Authorizationヘッダに Bearer JWTトークン を含めてAPIリクエストを行う
- 有効期限内なら、
- JWTトークンがLoacalStorageにまだない、またはあっても有効期限が切れていたら、
- JWTトークンの発行をリクエストし、
- LocalStorageに保存し、
- Authorizationヘッダに Bearer JWTトークン を含めてAPIリクエストを行う
- JWTトークンの発行をリクエストし、
- JWTトークンがLocalStorageにあり、
コメント