新着:JWTハンドブックを無料で入手して、JWTを深く学んでください!
JSON Web トークン(JWT)は、JSONオブジェクトとして当事者間で安全に情報を伝送するためのコンパクトで自己完結した方法を定義するオープンスタンダード(RFC 7519)です。この情報は、デジタル署名されているため、検証および信頼できます。JWTは、秘密(HMACアルゴリズムを使用)またはRSAまたはECDSAを使用した公開鍵/秘密鍵ペアを使用して署名できます。
JWTは当事者間の秘密を保護するために暗号化することもできますが、ここでは署名付きトークンに焦点を当てます。署名付きトークンは、トークンに含まれるクレームの整合性を検証できますが、暗号化されたトークンは、それらのクレームを他の当事者から隠蔽します。公開鍵/秘密鍵ペアを使用してトークンに署名した場合、署名は、秘密鍵を保持する当事者だけが署名したことを証明します。
JSON Web トークンが役立つシナリオをいくつか示します。
認証:JWTを使用する最も一般的なシナリオです。ユーザーがログインすると、その後の各リクエストにはJWTが含まれ、ユーザーはそのトークンで許可されているルート、サービス、およびリソースにアクセスできます。シングルサインオンは、オーバーヘッドが小さく、異なるドメイン間で簡単に使用できるため、現在ではJWTを広く使用している機能です。
情報交換:JSON Web トークンは、当事者間で安全に情報を伝送するための優れた方法です。JWTは(たとえば、公開鍵/秘密鍵ペアを使用して)署名できるため、送信者が自称する者であることを確認できます。さらに、署名はヘッダーとペイロードを使用して計算されるため、コンテンツが改ざんされていないことも検証できます。
コンパクトな形式では、JSON Web トークンはドット(.
)で区切られた3つの部分で構成されます。
したがって、JWTは通常、次のようになります。
xxxxx.yyyyy.zzzzz
各部分について詳しく見ていきましょう。
ヘッダーは通常、2つの部分で構成されます。トークンの種類(JWT)と使用されている署名アルゴリズム(HMAC SHA256またはRSAなど)です。
例:
{
"alg": "HS256",
"typ": "JWT"
}
次に、このJSONはBase64Urlエンコードされて、JWTの最初の部分になります。
トークンの2番目の部分はペイロードであり、クレームが含まれています。クレームは、エンティティ(通常はユーザー)に関する記述と追加データです。クレームには、登録済み、公開、プライベートの3種類があります。
登録済みクレーム:これらは、一連の便利な相互運用可能なクレームを提供するために必須ではありませんが推奨される、事前に定義されたクレームのセットです。その中には、iss(発行者)、exp(有効期限)、sub(サブジェクト)、aud(オーディエンス)、およびその他があります。
JWTはコンパクトであるため、クレーム名は3文字のみであることに注意してください。
公開クレーム:これらは、JWTを使用するユーザーが自由に定義できます。ただし、衝突を回避するために、IANA JSON Web トークンレジストリで定義するか、衝突耐性のある名前空間を含むURIとして定義する必要があります。
プライベートクレーム:これらは、それらを使用することに同意する当事者間で情報を共有するために作成されたカスタムクレームであり、登録済みクレームまたは公開クレームではありません。
ペイロードの例を以下に示します。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
ペイロードは次にBase64Urlエンコードされて、JSON Web トークンの2番目の部分になります。
署名付きトークンでは、この情報は改ざんから保護されますが、誰でも読むことができます。秘密情報は、暗号化されていない限り、JWTのペイロード要素またはヘッダー要素に配置しないでください。
署名部分を作成するには、エンコードされたヘッダー、エンコードされたペイロード、シークレット、ヘッダーに指定されたアルゴリズムを取り、署名する必要があります。
たとえば、HMAC SHA256アルゴリズムを使用する場合は、署名は次の方法で作成されます。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
署名は、メッセージが途中で変更されていないことを検証するために使用され、秘密鍵で署名されたトークンでは、JWTの送信者が自称する者であることを検証することもできます。
出力は、ドットで区切られた3つのBase64-URL文字列であり、HTMLとHTTP環境で簡単に渡すことができ、SAMLなどのXMLベースの標準と比較してよりコンパクトです。
以下は、前のヘッダーとペイロードがエンコードされ、秘密で署名されたJWTを示しています。
JWTを試してこれらの概念を実践したい場合は、jwt.ioデバッガーを使用して、JWTをデコード、検証、および生成できます。
認証では、ユーザーが資格情報を使用して正常にログインすると、JSON Web トークンが返されます。トークンは資格情報であるため、セキュリティ上の問題を防ぐために細心の注意を払う必要があります。一般的に、必要以上の期間トークンを保持しないでください。
また、セキュリティ上の欠陥があるため、ブラウザのストレージに機密セッションデータを保存しないでください。
ユーザーが保護されたルートまたはリソースにアクセスする場合、ユーザーエージェントはJWTを、通常はBearerスキーマを使用してAuthorizationヘッダーで送信する必要があります。ヘッダーの内容は次のようになります。
Authorization: Bearer <token>
これは特定のケースではステートレスな認証メカニズムになる可能性があります。サーバーの保護されたルートは、Authorization
ヘッダーで有効なJWTを確認し、存在する場合は、ユーザーは保護されたリソースにアクセスできます。JWTに必要なデータが含まれている場合、特定の操作に対するデータベースのクエリが必要なくなる可能性がありますが、常にそうとは限りません。
JWTトークンをHTTPヘッダーを介して送信する場合は、サイズが大きくなりすぎないようにする必要があります。一部のサーバーは、ヘッダーに8KBを超えるデータを受け入れません。ユーザーのすべての権限を含めるなど、JWTトークンに多くの情報を埋め込もうとしている場合は、Auth0ファイングレイン認証などの代替ソリューションが必要になる場合があります。
トークンがAuthorization
ヘッダーで送信される場合、クッキーを使用しないため、クロスオリジンリソース共有(CORS)は問題になりません。
次の図は、JWTを取得してAPIまたはリソースにアクセスする方法を示しています。
/oauth/authorize
エンドポイントを経由します。署名付きトークンでは、トークンに含まれるすべての情報は、変更することはできませんが、ユーザーや他の当事者に公開されます。つまり、トークンに秘密情報を配置しないでください。
Simple Web Tokens(SWT)およびSecurity Assertion Markup Language Tokens(SAML)と比較した場合のJSON Web Tokens(JWT)の利点について説明します。
JSONはXMLよりも冗長性が低いため、エンコードされたサイズも小さくなり、JWTはSAMLよりもコンパクトになります。これにより、JWTはHTMLとHTTP環境で渡すのに適した選択肢になります。
セキュリティの観点から、SWTはHMACアルゴリズムを使用して共有秘密によってのみ対称的に署名できます。ただし、JWTとSAMLトークンは、署名のためにX.509証明書の形をした公開鍵/秘密鍵ペアを使用できます。あいまいなセキュリティホールを導入せずにXML Digital SignatureでXMLに署名することは、JSONに署名する際のシンプルさと比較して非常に困難です。
JSONパーサーは、オブジェクトに直接マッピングされるため、ほとんどのプログラミング言語で一般的です。逆に、XMLには自然なドキュメントからオブジェクトへのマッピングがありません。これにより、SAMLアサーションよりもJWTを簡単に扱うことができます。
使用方法に関しては、JWTはインターネット規模で使用されています。これは、特にモバイルにおいて、複数のプラットフォームでのJSON Webトークンのクライアント側処理の容易性を示しています。
エンコードされたJWTとエンコードされたSAMLの長さの比較
JSON Webトークンについてさらに詳しく知りたい場合、または独自のアプリケーションで認証を実行するために使用を開始したい場合は、OktaのAuth0にあるJSON Webトークンランディングページを参照してください。
今すぐJWTを始めましょう
ツールの使用を開始する