Gravid Banner

Amazon API Gateway 403 Bad Request

Today I spent several hours trying to get a new API on Amazon API Gateway authenticating with an API Key. I don’t always find AWS the easiest platform to work with. The documentation is often incomplete and not entirely well-organised.

The documentation for API Keys is located here, and the process can be summarised as follows

  • Create the API in API gateway
  • Create an API Stage
  • Deploy the API
  • Edit the Method request and check the box saying API key required
  • From the side panel choose API key, and create a new API Key
  • Give it a name and let Amazon auto-generate the key
  • From the side panel choose Usage Plan and create a new Usage Plan
  • Open the usage plan and on the Associated API Keys panel add your new API Key
  • On the Associated Stages panel click Add API Stage and associate it with the API and the stage you defined earlier
  • Deploy the API
  • Test it!

A couple of the steps are a bit circular, you can’t associate a usage plan with a stage until you have deployed a stage – but it did seem you need to redeploy the stage after associating the usage plan in order for it to kick in.

When I had done all of this I made my API call from PHP

function call($req, $d) {
    $apiKey = "xxx"; // my API Key
    $url = "https://???.amazonaws.com/???/"; // My AWS Gateway API URL
    $auth = "x-api-key: $apiKey";
    
    $data = "{\"data\":\"$req\"}";
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', $auth]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($status==200) {
      $j = json_decode($output);
      
      // handle the reply
      }
    
    // handle any errors
  }
PHP

Unfortunately when I ran this I got the dreaded 403 – Forbidden response code. A lot of searching seemed to indicate I had done everything right, but I still wasn’t getting in.

I recreated the API call in Postman and got the same result. Looking at the response from Postman however, I found one additional piece of information. A header called x-amzn-errortype with a value of “Bad Request”.

AWS Certified Cloud Practitioner (Ad)

Sadly this does not appear on Amazon’s 403 troubleshooting list. A lot more searching turned up an obscure post on the Amazon Developer’s forums – Resource forbidden due to invalid API Key

One of the answers tho this suggests checking that the Usage Plan feature is enabled on your AWS account, but tying the following into the AWS Console

aws apigateway get-account

In my case it was not there. The response goes on to tell you how to enable it

aws apigateway update-account --patch-operations op='add',path='/features',value='UsagePlans'

Once I had run this and re-deployed the API my Postman call was still returning a 403 error. So I deleted the API Key, and the Usage Plan, and then created and attached new ones. After all this I got a response status of 200.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *