この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
CX事業本部デリバリー部の吉川です。
API GatewayでAPIにIAM認証をかけて、Node.jsでSigV4署名ヘッダを作成してリクエストしてみる | DevelopersIO
上記行う機会があり、AWS SDKのV3で実現するサンプルを書いてみました。
環境
- node 16.17.0
- npm 8.18.0
- typescript 4.8.2
- @aws-sdk/protocol-http 3.162.0
- @aws-sdk/signature-v4 3.162.0
- @aws-sdk/credential-provider-node 3.162.0
- @aws-crypto/sha256-universal 2.0.2
- undici 5.10.0
HTTPクライアントにはundiciを使います。
依存パッケージをインストール
npm i @aws-sdk/protocol-http @aws-sdk/signature-v4 @aws-sdk/credential-provider-node @aws-crypto/sha256-universal undici
TypeScriptコード
こちらのIssueやAWS SDKのリファレンスを参考に次のようにコードを書いてみました。
import { HttpRequest } from '@aws-sdk/protocol-http';
import { SignatureV4 } from '@aws-sdk/signature-v4';
import { Sha256 } from '@aws-crypto/sha256-universal';
import { defaultProvider } from '@aws-sdk/credential-provider-node';
import { request } from 'undici';
const main = async () => {
const apiUrl = new URL('https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/');
const signatureV4 = new SignatureV4({
service: 'execute-api',
region: 'ap-northeast-1',
credentials: defaultProvider(),
sha256: Sha256,
});
const httpRequest = new HttpRequest({
headers: {
'content-type': 'application/json',
host: apiUrl.hostname,
},
hostname: apiUrl.hostname,
method: 'POST',
path: apiUrl.pathname,
});
const signedRequest = await signatureV4.sign(httpRequest);
console.log({ signedRequest });
const response = await request(apiUrl.toString(), {
headers: signedRequest.headers,
method: 'POST',
});
console.log({
statusCode: response.statusCode,
body: await response.body.json(),
});
};
main();
credentials: defaultProvider()
の代わりにアクセスキーをそのままセットもできます。
const signatureV4 = new SignatureV4({
service: 'execute-api',
region: 'ap-northeast-1',
- credentials: defaultProvider(),
+ credentials: {
+ accessKeyId: 'XXXXXXXXX',
+ secretAccessKey: 'XXXXXXXXX',
+ },
sha256: Sha256,
});
冒頭のブログと同様に検証用API Gatewayを作成し、esbuild-registerで実行して意図通り動作することを確認しました。
参考
- 署名バージョン 4 の署名キーを取得する方法の例 - AWS 全般のリファレンス
- @aws-sdk/signature-v4 | AWS SDK for JavaScript v3
- aws/aws-sdk-js-crypto-helpers: AWS Cryptographic helpers for Javascript and Node.js
SignatureV4
is calculating a different signature to AWS, and I don't understand why · Issue #2996 · aws/aws-sdk-js-v3- signature-v4: generates wrong signature if method is lowercase · Issue #3612 · aws/aws-sdk-js-v3
- signature-v4 misses README doc · Issue #3615 · aws/aws-sdk-js-v3
- [aws-sdk/signature-v4] getCanonicalHeaders fails on undefined header value · Issue #3788 · aws/aws-sdk-js-v3
- Amazon API GatewayのIAM認証の動作を確認しました | ヤマムギ
- API GatewayでAPIにIAM認証をかけて、Node.jsでSigV4署名ヘッダを作成してリクエストしてみる | DevelopersIO