こうこく
作 ▸
改 ▸

AWS Lambdaプロキシ統合のイベントからCognitoユーザープールの属性を取得 (Node.js)

  • オーソライザーにCognitoユーザープールを設定していれば、event.requestContext.authorizer.claims に入ってくる。
  • もしくは event.headers.Authorization から生のIDトークンを取得してパースする。

イベントの claims を使う方法

Node.jsの場合、Lambdaハンドラに渡されてきた event.requestContext.authorizer.claims の中身は下記のような感じになってる。

event.requestContext.authorizer.claims
{
	"sub": "4216ac0c-b092-493a-8567-1fff71b4XXXX",
	"aud": "s65q9nma0510d6h15g9t8XXXX",
	"event_id": "afc54790-3048-4d50-b458-01f1dfbc7fc8",
	"token_use": "id",
	"auth_time": "1573022214",
	"iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_XXXXXXXXX",
	"cognito:username": "kiriukun",
	"exp": "Wed Nov 06 07:36:54 UTC 2019",
	"iat": "Wed Nov 06 06:36:54 UTC 2019"
}

ネットで見かけた限りでは、emailがある場合は同様に claims に入ってる模様。それ以外のユーザー属性は調べてないので不明。ユーザー名は cognito:username という風に不思議な感じなので注意。

auth_time が数値ではなく文字列だったり、exp はそもそもタイムスタンプじゃなかったりする。公式マニュアルでは数値のタイムスタンプなのに。

残り時間を確認するなら exp をパースするより auth_time に3600秒 (IDトークンの有効期限) を足して計算したほうが楽かと思ったけど、auth_time はIDトークンをリフレッシュしても値が変化しないので、残り時間の算出には使えない。

exp のパースが面倒なら、生のIDトークンをデコードして、マニュアル通りの exp を取り出した方が楽かも。

生のIDトークンを使う方法

生のIDトークンを取得するなら event.headers を見る。

const handler = async (event) => {
	// Authorizationヘッダの名称が大文字始まりでも小文字始まりでも取得できるように
	const authorization = event.headers.Authorization || event.headers.authorization;
	if (authorization) {
		const idToken = authorization.split('Bearer ')[1];
		console.log('IDトークン', idToken);
	}
};

module.exports = { handler };

IDトークンはJSON Web Tokenなので、Node.jsなら jsonwebtoken 等でデコードできる。

インストール
npm install jsonwebtoken
デコード
const jwt = require('jsonwebtoken');
const claims = jwt.decode('IDトークンの値');

これで取得できた claims の中身を見ると、こちらは以下のようにマニュアル通りのフォーマットになっている。日付がタイムスタンプ形式で扱いやすい。

パースしたIDトークン
{
	"sub": "aed7ad78-f440-47b3-ad9d-4af84f80XXXX",
	"aud": "4lbri730rpvdagk74g1a3eXXXX",
	"event_id": "f91fcfe0-3bbb-4db4-a834-c8e2051c0fb2",
	"token_use": "id",
	"auth_time": 1571809319,
	"iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_XXXXXXXXX",
	"cognito:username": "kiriukun",
	"exp": 1571812919,
	"iat": 1571809319
}

この方法でIDトークンの残り時間を算出するには以下の通り。

const jwt = require('jsonwebtoken');

const idToken = 'IDトークン';
const decodedIdToken = jwt.decode(idToken);

const expSec = decodedIdToken.exp;
const nowSec = Math.floor(Date.now() / 1000);  // Date.now() はミリ秒だから秒にする
const remainSec = expSec - nowSec;

console.log('残り秒数', remainSec);
この記事に何かあればこちらまで (非公開)