How to access HTTP headers for request to AWS API Gateway using Lambda?

Amazon Web-ServicesAws LambdaAws Api-Gateway

Amazon Web-Services Problem Overview


I see in the API Gateway FAQ that it is possible to access the request headers sent to the API Gateway...

> If you already utilize OAuth tokens or any other authorization > mechanism, you can easily setup API Gateway not to require signed API > calls and simply forward the token headers to your backend for > verification.

However, I can find no example of how to do so in the documentation and it is unclear how to access this data using Lambda.

I am able to set up an open API and gain access to the JSON object that is part of a POST (Walkthrough: API Gateway and Lambda Functions), but in order to implement a OAuth 2.0 style API with my own provider I need access to the "Authorization" header.

My preference is to set this up using Lambda and Java 8, but an example using node.js would also be helpful in understanding how to accomplish this.

Amazon Web-Services Solutions


Solution 1 - Amazon Web-Services

First, you need to trap the Authorization header from the HTTP GET request. Then you need to map that value to the Lambda event object.

Go to the API method dashboard and click on Method Request. In there you can add an HTTP Request Header called Authorization as shown below.

HTTP Request Headers

This will trap the Authorization header so you can use it later.

Now go back to the method dashboard and click on Integration Request. From here you can pass the value of the header into the Lambda function by using a mapping like this.

{
    "Authorization": "$input.params('Authorization')"
}

Now in your Lambda function you can get the value like this.

event.Authorization

Solution 2 - Amazon Web-Services

You can use the following Mapping Template in the Integration Request to generically map all path, query, and header parameters into the Lambda event. You will still need to register them in the Method Request section of the API Gateway but you can at least decouple the Mapping Template from the specific parameters you want to use. This way you don't have to change the Mapping Template code each time you change headers, query, or path parameters.

I wrote a blog post that gives more detail and some explanation of the Mapping Template: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/

Here is the Mapping Template you can use:

{
  "method": "$context.httpMethod",
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end
    
    #end
  },
  "queryParams": {
    #foreach($param in $input.params().querystring.keySet())
    "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
    
    #end
  },
  "pathParams": {
    #foreach($param in $input.params().path.keySet())
    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end
    
    #end
  }  
}

Solution 3 - Amazon Web-Services

You need to create input mapping inside Integration Request panel on the dashboard screen describing your API method.

Following code translates name query input parameter into Lambda Event input object:

{
   "name": "$input.params('name')"
}

Screenshot:

API Dashboard screenshot

You can find more info about this in the original API Gateway to Lambda input thread on AWS Forums.

Solution 4 - Amazon Web-Services

while this is an old thread, I have found it best to use lambda proxy integration for the purpose. With this you do not have to configure anything in the API gateway and you get all the headers in your lambda function...

https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html

Solution 5 - Amazon Web-Services

As per Prabhat's answer setting up with the lambda proxy integration request is the simplest way to do this, after which you can access the request headers, path parameters and query parameters via

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']

Solution 6 - Amazon Web-Services

This is an example event object:

{
"requestContext": {
    "elb": {
        "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a"
    }
},
"httpMethod": "GET",
"path": "/lambda",
"queryStringParameters": {
    "query": "1234ABCD"
},
"headers": {
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "accept-encoding": "gzip",
    "accept-language": "en-US,en;q=0.9",
    "connection": "keep-alive",
    "host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
    "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476",
    "x-forwarded-for": "72.12.164.125",
    "x-forwarded-port": "80",
    "x-forwarded-proto": "http",
    "x-imforwards": "20"
},
"body": "",
"isBase64Encoded": false

}

The event object contains "headers" in it, you can access request headers sent to API gateway by using: event.headers.<header key>

Solution 7 - Amazon Web-Services

The solution by kennbrodhagen worked great for me, see his answer and blog for the details. Since the poster expressed a preference for Java implementation, and it took me a while to figure out how to implement Kenn's handler in java, I'm just sharing the Java code that corresponds:

public class MyHandler implements RequestHandler<Map<String,Object>,String> {

    @Override
    public String handleRequest(Map<String,Object> eventMap, Context context) {
        LambdaLogger logger = context.getLogger();
        logger.log("Body:" + eventMap.get("body"));
        logger.log("Headers:" + eventMap.get("headers"));
        logger.log("Method:" + eventMap.get("method"));
        logger.log("Params:" + eventMap.get("params"));
        logger.log("Query:" + eventMap.get("query"));
        return("{}");
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJaredHatfieldView Question on Stackoverflow
Solution 1 - Amazon Web-ServicesDavid FevreView Answer on Stackoverflow
Solution 2 - Amazon Web-ServiceskennbrodhagenView Answer on Stackoverflow
Solution 3 - Amazon Web-ServicesadamkonradView Answer on Stackoverflow
Solution 4 - Amazon Web-ServicesPrabhatView Answer on Stackoverflow
Solution 5 - Amazon Web-ServicesJonathanView Answer on Stackoverflow
Solution 6 - Amazon Web-ServicesJishnuView Answer on Stackoverflow
Solution 7 - Amazon Web-ServicesmojokenView Answer on Stackoverflow