アプリケーションの認証方法に Amazon Cognito ユーザープールを使用したいです。クライアントがアプリケーションに送信する ID とアクセストークンを安全に検証する方法が必要です。
簡単な説明
クライアントがユーザープールを使用してアプリケーションを認証すると、Cognito はデコード、読み取り、変更用のJSON ウェブトークン (JWT) を送信します。JWT から Cognito ユーザーの詳細を取得するには、トークンをデコードして署名を検証します。
重要: リソースへのアクセスを許可する前に、署名を確認する必要があります。
解決策
Cognito が JWT を発行したことを確認する
次の JavaScript のコードを使用します。
import { CognitoJwtVerifier } from "aws-jwt-verify";
// Verifier that expects valid access tokens:
const verifier = CognitoJwtVerifier.create({
userPoolId: "user_pool_id",
tokenUse: "access",
clientId: "client_id",
});
try {
const payload = await verifier.verify(
"eyJraWQeyJhdF9oYXNoIjoidk..." // the JWT as string
);
console.log("Token is valid. Payload:", payload);
} catch {
console.log("Token not valid!");
}
注: user_pool_id は実際のプール ID に、client_id はお使いのアプリクライアント ID に置き換えます。ID トークンで、tokenUse フィールドを "id" に更新します。使用可能なパラメーターのリストについては、GitHub のウェブサイトで 「aws-jwt-verify」を参照してください。
別のプログラミング言語を使用している場合は、JWT のウェブサイトで「jwt.io ライブラリ」を参照するか、OpenID のウェブサイトで 「OpenID Connect ライブラリ」を参照してください。コード例については、GitHub のウェブサイトで「Amazon Cognito JWT トークンのデコードと検証」を参照してください。
Cognitoは、ID トークン、アクセストークン、更新トークンという最大 3 つのトークンを返します。REST API、AWS Amplify、またはAWS SDK を使用してユーザーを認証すると、3 つのトークンすべてが取得されます。
Cognito がホストする UI の場合、取得するトークンは、使用する認証付与のタイプによって異なります。暗黙的付与を使用する場合、アクセストークンと ID トークンのみを取得することになります。認証コードグラント付与では、アクセストークン、ID トークン、更新トークンが返されます。クライアント認証情報付与では、アクセストークンのみが返されます。
アクセストークンと ID トークンには、ヘッダー、ペイロード、署名が含まれます。クライアントは更新トークンをデコードまたは検証できません。
ID トークンヘッダーのサンプルを次に示します。ヘッダーには、キー ID ("kid") と、トークンの署名に使用するアルゴリズム ("alg") が含まれています。RS256 アルゴリズムは SHA-256 を使用した RSA 署名です。
{
"kid": "key_id_example=",
"alg": "RS256"
}
ユーザーに関する情報と、トークンの作成と有効期限のタイムスタンプを含むペイロードの例を次に示します。
{
"sub": "aaaaaaaa-bbbb-cccc-dddd-example",
"aud": "audience_example",
"email_verified": true,
"token_use": "id",
"auth_time": 1500009400,
"iss": "https://cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_example",
"cognito:username": "anaya",
"exp": 1500013000,
"given_name": "Anaya",
"iat": 1500009400,
"email": "anaya@example.com"
}
署名は、ヘッダーとペイロードをハッシュ化および暗号化した組み合わせです。
Cognito は、ユーザープールごとに 2 つの RSA キーペアを生成します。各ペアの秘密鍵は、ID トークンまたはアクセストークンに暗号で署名するのに使用します。公開鍵は次の場所のアドレスにあります。
https://cognito-idp.region.amazonaws.com/userPoolId/.well-known/jwks.json
注: region はユーザープールのある AWS リージョンに、userPoolId は実際のユーザープール ID に置き換えます。
JSON ファイル (jwks.json) は次のフォーマットで構成されています。
{ "keys": [{
"alg": "RS256",
"e": "AQAB",
"kid": "abcdefghijklmnopqrsexample=",
"kty": "RSA",
"n": "lsjhglskjhgslkjgh43lj5h34lkjh34lkjht3example",
"use": "sig"
}, {
"alg":
"RS256",
"e": "AQAB",
"kid": "fgjhlkhjlkhexample=",
"kty": "RSA",
"n": "sgjhlk6jp98ugp98up34hpexample",
"use": "sig"
}]
}
Cognito JWT の署名を確認するには、トークンのヘッダーと一致するキー ID のパブリックキーを検索します。複数のライブラリを使用してトークンの署名を検証し、有効期限やユーザー名などの値を抽出します。
トークンの有効期限が切れていないことを確認するのがベストプラクティスです。また、ペイロード内のオーディエンス ("aud") が Amazon Cognito ユーザープールで作成したアプリクライアント ID と一致することを確認してください。aws-jwt-verify ライブラリがこれらの値を自動的にチェックします。詳細については、GitHub のウェブサイトで「aws-jwt-verify」を参照してください。
公開鍵をキャッシュする
JWKS エンドポイントの公開鍵は希にしかローテーションされないため、トークンを検証するたびにエンドポイントからダウンロードする必要はありません。代わりに、公開鍵をダウンロードして、JWT トークン検証ロジックを使用するローカルマシンにキャッシュしてください。
"kid" は公開鍵の一意の識別子です。JWT トークンを検証するには、ローカルキャッシュをチェックして、トークンヘッダーの "kid" がキャッシュ内にあるかどうかを確認します。キャッシュがない場合は、JWKS エンドポイントから公開鍵をダウンロードし、キャッシュを更新します。
複数の方法でトークンの有効期限または失効状況を確認する
更新トークンを取り消したり、アクセストークンを無効にしたりすることはできますが、ID トークンを取り消すことはできません。JWT 検証ライブラリはトークンの有効期限を確認しますが、トークンの失効状態は確認しません。失効ステータスのチェックには、サーバー側のチェックが必要です。
関連情報
ユーザープール JSON ウェブトークン (JWT) について
AWS CLI を使用して Amazon Cognito の JWT トークンを取り消す方法を教えてください