いちおう公式にサンプルがあるんですが、そのままだとちょっとデコードし辛いので簡単にデコードできるように雑なコードを書いた。

package.json


まずpackage.jsonです。3つのライブラリを使用しています。

  • AWS CognitoのJWKを取得するためにnode-fetch
  • 取得したJWKをPEMに変換するためにjwk-to-pem
  • アクセストークンをデコードするためのjsonwebtoken
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "jwt-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"author": "YoshinoriN",
"devDependencies": {},
"dependencies": {
"jsonwebtoken": "8.5.1",
"jwk-to-pem": "2.0.1",
"node-fetch": "2.6.0"
}
}

これでnpm installします。

コード


こんな感じです。AWS Cognitoのjwksには2つのJWKが含まれているのですが、2つ目をベタで指定(json.keys[1]のところ)しています。1つ目は何にJWKなのかちょっとよくわかりませんでした…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const { verify } = require('jsonwebtoken');
const jwkToPem = require('jwk-to-pem');
const fetch = require('node-fetch');

const jwkUrl = process.argv[2];
const token = process.argv[3];

fetch(jwkUrl)
.then(response => response.json())
.then(json => {
const pem = jwkToPem(json.keys[1]);
verify(token, pem, function(err, decodedToken) {
if (!err == null) {
console.log(err)
} else {
console.log(decodedToken)
}
});
})
.catch(error => {
console.log(error);
});

これをindex.jsとかそんな感じの名前で保存します。

デコードする


下記のようにJWKのURLとアクセストークンを引数にわたして実行します。

1
$ node index.js <your jwk url> <jwt>

すると下記のような結果が得られると思います。クレーム情報はCognitoの設定によるので必ずしも下記と一致するわけではないです。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
sub: 'aaaaaa-bbbbbbb',
event_id: 'sssssssssssssssssssssssssssss',
token_use: 'ddddd',
scope: 'test.test.example',
auth_time: 1568286190,
iss: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
exp: 1568289123,
iat: 1568286110,
jti: 'ttt-ttt-ttt-ttt-ttt',
client_id: 'aaaaaaaaaaa',
username: 'testuser'
}

おわり。