この記事は 株式会社うるる(ULURU) Advent Calendar 2023 の24日目の記事です。
はじめに
クリスマスイブですね、皆様いかがお過ごしでしょうか???
私は明日のクリスマスとM1決勝に向けて、気持ちを高めております。
今回は最近触れる機会が多かったJWTについて、自分の備忘録の意味も込めてまとめてみました。
年末の隙間時間にでも見ていただけると嬉しいです。
JWTとは
JWT(JSON Web Token)は、データの安全な転送を行うためのJSON形式のトークン規格です。ヘッダ、ペイロード、署名から成り立ち、認証や情報共有に使用されます。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWTの構造
JWTは「ヘッダー」「ペイロード」「シグネチャ」の3つから生成されています。それぞれは、Base64でエンコードされており、. (ドット)で接続されています。
ヘッダー
ヘッダー(Header)は、JWTトークンの構造と署名アルゴリズムに関する情報を含む部分です。
{
"alg": "HS256",
"typ": "JWT"
}
alg
alg(Algorithm): このフィールドは、JWTの署名アルゴリズムを指定します。JWTを生成する際と検証する際に使用されるアルゴリズムです。一般的な値には "HS256"(HMAC SHA-256)、"RS256"(RSA SHA-256)、"ES256"(ECDSA SHA-256)などがあります。
typ
typ(Type): このフィールドは、JWTトークンのタイプを示します。通常は "JWT" と設定されます。
ペイロード
ペイロード(Payload)は、トークンに含まれる情報を格納する部分です。
{
"iss": "example.com",
"sub": "1234567890",
"aud": "myapp",
"exp": 1696135807,
"nbf": 1696132200,
"iat": 1696132200,
"jti": "unique-jwt-id"
}
上記は、JWTのペイロードの例です。ペイロードはJSON形式で表現されており、RFCに登録済みのクレーム名(下記)もありますが、使用は必須ではありません。カスタムのクレーム(Claims)を使用することもできます。
クレーム | 説明 |
---|---|
iss | JWT発行者 |
sub | JWT発行者から払い出されたユーザ識別子。 |
aud | JWTを利用することが想定された主体の識別子一覧 |
exp | JWTの有効期限を示す。 |
nbf | JWTが有効になる日時を示す |
iat | JWTを発行した時刻を示す |
jti | JWTのための一意な識別子。JWTのリプレイを防ぐことに利用する |
typ | typヘッダパラメータと同じ値空間および同じ規則が適用される |
署名
署名(Signature)はヘッダとペイロードを含めたデータの署名がこのセクションに含まれます。署名の生成には、秘密鍵を使用し、署名の検証には公開鍵が使用されます。これによって正しい発行者が発行したIDトークンであることを確認できます。
JWTの認証フロー
- ユーザーの認証: ユーザーは通常、ユーザー名とパスワード、または他の認証手段を使用してアプリケーションにログインします。認証が成功すると、アプリケーションはユーザーに対してJWTを発行します。
- JWTの発行: 認証サーバーまたはバックエンドサービスは、ユーザーを識別する情報(例: ユーザーID、ロール、有効期限など)を含むJWTを生成します。このJWTは、ユーザーのクライアントに返されます。
- JWTの保存: ユーザーのクライアント(通常はブラウザやモバイルアプリ)は、受け取ったJWTを安全に保存します。通常、ブラウザではクッキーまたはローカルストレージ、モバイルアプリではメモリやセキュアストレージが使用されます。
- APIへのアクセス: ユーザーがAPIエンドポイントにアクセスする際、JWTをHTTPヘッダーまたはクエリパラメータとして送信します。一般的に、"Authorization"ヘッダーにBearerトークンとして送信されます。
- JWTの検証: APIサーバーは、受信したJWTを検証します。検証には、JWTの署名を検証し、トークンの有効期限を確認するなどのステップが含まれます。
- アクセス許可の確認: JWT内の情報を使用して、APIサーバーはユーザーが要求した操作を実行できるかどうかを確認します。JWTには、ユーザーのロールや権限情報が含まれていることが一般的です。
- リソースの提供: JWTが検証され、ユーザーがアクセス権を持っている場合、APIサーバーは要求されたリソースまたはサービスを提供します。
メリット
- シンプルで軽量: JWTはJSON形式でデータを表現するため、シンプルで軽量なデータ構造を使用します。これにより、データの交換が効率的に行えます。
- クロスドメイン通信: クロスドメイン通信の際に、JWTを使用することで認証を容易に行えます。クッキーを使用せず、ヘッダーにトークンを含めることができます。
- 権限管理: JWTのペイロードには権限情報を含めることができ、アクセス制御を簡単に行えます。
デメリット
- セキュリティリスク: トークンはクライアント側に保存されるため、クロスサイトスクリプティング(XSS)攻撃やクロスサイトリクエストフォージェリ(CSRF)攻撃などのセキュリティリスクに対処する必要があります。適切なセキュリティ対策が必要です。
- 情報の暴露: トークンはデータを含んでおり、ヘッダーとペイロードはBase64エンコードされています。これにより、情報が暴露されるリスクがあるため、機密性の高い情報をトークンに含める際には注意が必要です。
- トークンの管理: トークンは有効期限があるため、期限切れのトークンの管理やリフレッシュトークンの実装が必要です。
- 秘密鍵の管理: 非対称鍵を使用する場合、秘密鍵の安全な管理が必要です。秘密鍵が漏洩すると、システムのセキュリティが脆弱になります。
おまけ
こちらのサイトでjwtの構成を簡単に見ることができるので、気になる方は確認してみてください。
最後に
今までなんとなくで理解していたJWTについて学ぶ良い機会となりました。1つ1つの技術について深ぼると、楽しいことに気づいた2年目の冬でした。。(おそい)
今日の夜はM1を深ぼろうと思います!!!
明日は@okamoto-shun-uluruさんの投稿です!お楽しみに!!