この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、Node.jsとTypeScriptで、Amazon CognitoのJWTのデコード、およびJWTを作成してテストする方法を確認してみました。
※JWTのVerify(検証)は本記事では試しません。
やってみた
環境
- typescript@3.9.10
- node v14.17.0
インストール
JWTのデコードにはjwt-decodeを使用します。Auth0社が提供するパッケージです。
$ npm i jwt-decode
テスト用のJWTの作成にはjsonwebtokenを使用します。現在19,000以上のDependentsで使われているパッケージです。
$ npm i jsonwebtoken
# TypeScript環境の場合
$ npm i -D @types/jsonwebtoken
JWTをデコードする
まずデコード対象のCognitoのトークンを取得します。実際にはクライアント側での認証で取得されリクエストで送信されますが、ここでは下記方法で手動で取得してみます。
CognitoユーザーのIDトークンを取得できました。
$ npm run get-my-user-id-token
> aws-cdk-v2-project@0.1.0 get-my-user-id-token
> dotenv -e .env -- ./node_modules/.bin/ts-node ./get-cognito-my-user-id-token-helper.ts
ID_TOKEN="eyJraWQiOiJQZWlVNlpaQnJEWmJNTHRobmRNMjhza1Y3Q0tQTERpMlA4..."
jwt-decode
を使用してCognitoのJWTをデコードする処理です。デバッグのために取得したIDトークンを記載します。
decode-jwt.ts
import jwt_decode from 'jwt-decode';
export const get_jwt_decoded = (
token: string
): {
[name: string]: string;
} => {
const decoded = jwt_decode<{ [name: string]: string }>(token);
console.log(decoded); //デバッグ用
return decoded;
};
//デバッグ用
get_jwt_decoded(
'eyJraWQiOiJQZWlVNlpaQnJEWmJNTHRobmRNMjhza1Y3Q0tQTERpMlA4...'
);
上記スクリプトを実行すると、JWTがデコードされた内容が取得できました!
$ npx ts-node decode-jwt.ts
{
sub: '88ffb38c-5c6b-4756-9770-76b45ff2fe71',
email_verified: true,
iss: 'https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxx',
'cognito:username': '88ffb38c-5c6b-4756-9770-76b45ff2fe71',
origin_jti: '6a039aec-1b38-4eef-b38a-9deff64853b3',
aud: '3u95of1slb4921q28vqaeomibg',
event_id: '0b468336-2d3c-48d7-ba17-209e88db3b06',
token_use: 'id',
auth_time: 1653142936,
exp: 1653146536,
iat: 1653142936,
jti: 'e4c85ebc-a3d9-45f3-9510-73be008aec16',
email: 'user@example.com'
}
JWTを作成してテストする
前節の処理をテストするために、JWTを作成するJestのテストを作成します。
テスト用のJWTの作成はjsonwebtoken
を使用します。
test/decode-jwt.test.ts
import { sign } from 'jsonwebtoken';
import { get_jwt_decoded } from '../decode-jwt';
test('get_jwt_decoded', () => {
const jwtPayload = {
sub: '12345678-xxxx-1234-xxxx-123456789012',
email: 'user@example.com',
};
const jwtSecret = 'jwt_secret';
const token = sign(jwtPayload, jwtSecret);
const res = get_jwt_decoded(token);
expect(res).toStrictEqual({
sub: '12345678-xxxx-1234-xxxx-123456789012',
email: 'user@example.com',
iat: expect.anything(),
});
});
テストを実行してみると、作成したJWTでテストができています!
npx jest test/decode-jwt.test.ts
PASS test/decode-jwt.test.ts (5.011 s)
✓ get_jwt_decoded (15 ms)
console.log
{
sub: '12345678-xxxx-1234-xxxx-123456789012',
email: 'user@example.com',
iat: 1653145828
}
at Object.<anonymous>.exports.get_jwt_decoded (decode-jwt.ts:9:11)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.055 s, estimated 6 s
Ran all test suites matching /test\/decode-jwt.test.ts/i.
おわりに
Node.jsとTypeScriptで、Amazon CognitoのJWTのデコード、およびJWTを作成してテストする方法を確認してみました。
Cognito認証により取得されたIDトークンから情報を取得して他の処理に使うことはよくあると思うので、そういう場合に役に立つと思います。
参考
以上