LoginSignup
1
0

More than 1 year has passed since last update.

API Gateway + LambdaのAPIにIAM認証で署名付きリクエストを送る(javascript, typescript)

Posted at

概要

APIGatewayのREST APIを使って構築したweb APIをIAM認証(accesskeyとsecretkeyを使った認証)で署名付きのリクエストを送信するサンプル。

参考にさせていただいた記事

IAMは対象のLamda関数のARNを指定した、 lambda:InvokeFunctionUrl のアクションのみを許可したユーザを作成しています。

javascriptとtypescriptのケース両方使うことがあるので、自分用のメモとして参考にさせていただいた記事のコードを少し書き直してます。

実装

javascript

$ npm install --dev aws-sdk axios
const core = require('aws-sdk/lib/core');
const aws = require('aws-sdk');
const axios = require('axios');

// アクセスキーとシークレットアクセスキーを設定
const accessKey = 'xxxxxxx';
const secretKey = 'xxxxxxx';
const credential = new aws.Credentials(accessKey, secretKey);


function main() {
  const serviceName = "execute-api";

  const url = "https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/";

  const options = {
    url: url,
    headers: {}
  };

  const parts = options.url.split("?");
  const host = parts[0].substr(8, parts[0].indexOf("/", 8) - 8);
  const path = parts[0].substr(parts[0].indexOf("/", 8));
  const querystring = parts[1];
  const data = {
    /* payload */
  };

  const now = new Date();
  options.headers.host = host;
  options.pathname = () => path;
  options.methodIndex = 'post';
  options.search = () => querystring ? querystring : "";
  options.region = 'ap-northeast-1';
  options.method = 'POST';
  options.body = JSON.stringify(data);

  const signer = new core.Signers.V4(options, serviceName);

  signer.addAuthorization(credential, now);

  axios.post(url, data, options).then((r) => {
    console.log(r);
  }).catch((e) => {
    console.error("failed to request: ", e.response.status, e.code, e.response.data);
  });
}

main();

Typescript

import axios from 'axios'
import { Credentials } from 'aws-sdk'
import { SignatureV4 } from '@aws-sdk/signature-v4'
import { Sha256 } from '@aws-crypto/sha256-js'
import { HttpRequest } from '@aws-sdk/protocol-http'

const main = async () => {
  const accessKey = 'xxxxxxxxx'
  const secretKey = 'xxxxxxxxx'
  const creds = new Credentials(accessKey, secretKey)

  const serviceName = 'execute-api'
  const url =
    'https://xxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/'
  const parts = url.split('?')
  const host = parts[0].substr(8, parts[0].indexOf('/', 8) - 8)
  const path = parts[0].substr(parts[0].indexOf('/', 8))
  const data = {
    /* payload */
  }

  const req = new HttpRequest({
    headers: {},
    hostname: host,
    method: 'POST',
    path: path,
  })

  const signer = new SignatureV4({
    credentials: creds,
    region: 'ap-northeast-1',
    service: serviceName,
    sha256: Sha256,
  })
  const signedHttpRequest = await signer.sign(req)

  try {
    const r = await axios.post(url, data, signedHttpRequest)
    console.log(r)
  } catch (e: any) {
    console.error(e)
  }
}

main()
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0