JWT(JSON Web Tokens)のマスター
Olivia Novak
Dev Intern · Leapcell

JSON Web Token(略してJWT)は、現在最も人気のあるクロスドメイン認証ソリューションです。この記事では、その原則と用法を紹介します。
I. クロスドメイン認証の問題
インターネットサービスは、ユーザー認証と切り離せません。一般的なプロセスは次のとおりです。
- ユーザーはユーザー名とパスワードをサーバーに送信します。
- サーバーが認証に成功すると、ユーザーの役割、ログイン時間など、関連するデータが現在のセッションに保存されます。
- サーバーはsession_idをユーザーに返し、それをユーザーのCookieに書き込みます。
- ユーザーからの後続のリクエストごとに、session_idがCookieを介してサーバーに返送されます。
- サーバーはsession_idを受信すると、事前に保存されたデータを検索し、それによってユーザーのIDを認識します。 このモデルの問題点は、スケーラビリティが低いことです。単一のマシンでは問題ありません。ただし、サーバークラスターまたはクロスドメインサービス指向アーキテクチャの場合、セッションデータの共有が必要であり、各サーバーはセッションを読み取ることができる必要があります。 たとえば、ウェブサイトAとウェブサイトBは、同じ会社の関連サービスであるとします。ユーザーがあるウェブサイトにログインすると、別のウェブサイトにアクセスしたときに自動的にログインすることが求められています。これをどのように実現すればよいでしょうか? 1つの解決策は、セッションデータを永続化し、データベースまたは他の永続レイヤーに書き込むことです。リクエストを受信した後、さまざまなサービスが永続レイヤーからデータをリクエストします。このソリューションの利点は、アーキテクチャが明確であることですが、欠点は、ワークロードが比較的大きいことです。さらに、永続レイヤーが失敗すると、単一障害点が発生します。 別の解決策は、サーバーがセッションデータを保存しないことです。すべてのデータはクライアントに保存され、リクエストごとにサーバーに返送されます。JWTは、このソリューションの代表的なものです。
II. JWTの原則
JWTの原則は、サーバーが認証後、次のようなJSONオブジェクトを生成してユーザーに返すことです。
{"name": "Alice", "role": "admin", "expiration time": "0:00, July 1, 2024"}
その後、ユーザーがサーバーと通信するときは、このJSONオブジェクトを返送する必要があります。サーバーは、このオブジェクトのみに基づいてユーザーのIDを判別します。ユーザーがデータを改ざんするのを防ぐために、サーバーはこのオブジェクトを生成するときに署名を追加します(詳細は後述します)。 サーバーはセッションデータを保存しなくなりました。つまり、サーバーはステートレスになり、拡張が容易になります。
III. JWTのデータ構造
実際のJWTは、おそらく次のようになります。
これは非常に長い文字列で、ドット(.)で3つの部分に区切られています。JWT内部に改行がないことに注意してください。ここでは、表示しやすいように数行で記述されています。 JWTの3つの部分は次のとおりです。
- ヘッダー(Header)
- ペイロード(Payload)
- 署名(Signature)
1行で記述すると、次のようになります。
Header.Payload.Signature
以下に、これら3つの部分を順番に紹介します。
3.1 ヘッダー
ヘッダー部分は、JWTのメタデータを記述するJSONオブジェクトであり、通常は次のようになります。 {"alg": "HS256", "typ": "JWT"} 上記のコードでは、alg属性は署名アルゴリズムを表し(algorithm)、デフォルトはHMAC SHA256(HS256と記述)です。typ属性は、このトークンのタイプを表し、JWTトークンは一律にJWTとして記述されます。 最後に、上記のJSONオブジェクトは、Base64URLアルゴリズムを使用して文字列に変換されます(詳細は後述します)。
3.2 ペイロード
ペイロード部分も、実際に送信する必要があるデータを格納するために使用されるJSONオブジェクトです。JWTは、選択のために7つの公式フィールドを定義しています。
- iss(issuer):発行者
- exp(expiration time):有効期限
- sub(subject):サブジェクト
- aud(audience):オーディエンス
- nbf(Not Before):有効期間
- iat(Issued At):発行時間
- jti(JWT ID):シリアル番号 公式フィールドに加えて、この部分でプライベートフィールドを定義することもできます。以下に例を示します。
{"sub": "1234567890", "name": "John Doe", "admin": true}
JWTはデフォルトで暗号化されておらず、誰でも読み取ることができることに注意してください。したがって、この部分に秘密情報を入れないでください。 このJSONオブジェクトも、Base64URLアルゴリズムを使用して文字列に変換する必要があります。
3.3 署名
署名部分は、データの改ざんを防ぐための最初の2つの部分の署名です。 まず、秘密鍵(secret)を指定する必要があります。このキーはサーバーのみが認識し、ユーザーに漏洩することはできません。次に、ヘッダーで指定された署名アルゴリズム(デフォルトはHMAC SHA256)を使用して、次の式に従って署名を生成します。
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
署名を計算した後、ヘッダー、ペイロード、署名部分を文字列に結合し、各部分の間に「ドット」(.)で区切り、ユーザーに返すことができます。
3.4 Base64URL
前述のように、ヘッダーとペイロードのシリアル化アルゴリズムはBase64URLです。このアルゴリズムは基本的にBase64アルゴリズムと似ていますが、いくつかの小さな違いがあります。 トークンとして、JWTはURLに配置される場合があります(例:api.example.com/?token = xxx)。Base64には3つの文字+、/、および=があり、これらはURLで特別な意味を持つため、置き換える必要があります。=は省略され、+は-に置き換えられ、/は_に置き換えられます。これがBase64URLアルゴリズムです。
IV. JWTの使用法
サーバーから返されたJWTを受信した後、クライアントはそれをCookieまたはlocalStorageに保存できます。 その後、クライアントがサーバーと通信するたびに、このJWTを持参する必要があります。Cookieに入れて自動的に送信できますが、これはクロスドメインできません。したがって、より良い方法は、HTTPリクエストヘッダーのAuthorizationフィールドに入れることです。
Authorization: Bearer <token>
別の方法は、クロスドメインの場合、JWTをPOSTリクエストのデータボディに配置することです。
V. JWTのいくつかの特徴
(1) JWTはデフォルトで暗号化されていませんが、暗号化することはできます。元のトークンを生成した後、秘密鍵で再度暗号化できます。
(2) JWTが暗号化されていない場合、秘密データをJWTに書き込むことはできません。
(3) JWTは、認証だけでなく、情報の交換にも使用できます。JWTを効果的に使用すると、サーバーがデータベースを照会する回数を減らすことができます。
(4) JWTの最大の欠点は、サーバーがセッション状態を保存しないため、使用中に特定のトークンを取り消したり、トークンのアクセス許可を変更したりすることができないことです。つまり、JWTが発行されると、サーバーが追加のロジックをデプロイしない限り、有効期限が切れるまで有効になります。
(5) JWT自体に認証情報が含まれています。漏洩すると、誰でもトークンのすべてのアクセス許可を取得できます。盗難を減らすために、JWTの有効期間は比較的短く設定する必要があります。より重要なアクセス許可については、使用時にユーザーを再度認証する必要があります。
(6) 盗難を減らすために、JWTはHTTPプロトコルを使用して平文で送信するのではなく、HTTPSプロトコルを使用して送信する必要があります。
Leapcell:Webホスティングに最適なサーバーレスプラットフォーム
最後に、Webサービスをデプロイするための最適なプラットフォームをお勧めします:Leapcell
1. 多言語対応
- JavaScript、Python、Go、またはRustで開発します。
2. 無制限のプロジェクトを無料でデプロイ
- 使用量に応じてのみ料金が発生します — リクエストも料金も発生しません。
3. 比類なきコスト効率
- アイドル料金なしの従量課金制。
- 例:25ドルで、平均応答時間60msで694万リクエストをサポートします。
4. 合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実用的な洞察のためのリアルタイムのメトリックとログ。
5. 簡単なスケーラビリティと高パフォーマンス
- 簡単な並行処理に対応するための自動スケーリング。
- 運用オーバーヘッドゼロ — 構築に集中するだけです。
Leapcell Twitter:https://x.com/LeapcellHQ