Search code examples
javascriptaws-api-gatewayamazon-iamaws-sdk-js

How to sign API Gateway URL that has a query string


I am trying to use SignatureV4 to sign a request for an API Gateway endpoint that uses IAM Authorizor. An issue is that I keep getting a 403 error whenever I append a query string to my URL, i.e. /pets?type=1. Everything works fine when a query string is not included, i.e. /pets

This is how I build a request:

const region = 'xxx'
const method = 'GET'
const protocol = 'https:'
const host = `xxx.execute-api.${region}.amazonaws.com`
const path = '/dev/pets'
const query = {
  type: 1,
}

const request = new HttpRequest({
  method: method,
  protocol: protocol,
  hostname: host,
  path: path,
  query: query,
  headers: {
    'Content-Type': 'application/json',
    host: host ,
  },
})

const signer = new SignatureV4({
  credentials: AWS.config.credentials,
  service: 'execute-api',
  region: region,
  sha256: Sha256,
})
const { headers } = await signer.sign(request)

const response = await fetch(`${protocol}//${host}${path}?type=1`, {
  headers,
  method
}).then((res) => res.json())

I've tried running the same query within Postman and it worked just fine. So, I have to assume that an issue is with my implementation.


Solution

  • An issue was due to getCanonicalQuery ignoring values that are not string or array:

    https://github.com/aws/aws-sdk-js-v3/blob/main/packages/signature-v4/src/getCanonicalQuery.ts#L19

    So, to fix this I had to swap my query to below:

    const query = {
      type: '1',
    }