Как получить доступ к заголовкам HTTP для запроса к AWS API Gateway с помощью Lambda?

Я вижу в Часто задаваемые вопросы по шлюзу API, что можно получить доступ к заголовкам запроса, отправленным на шлюз API...

Если вы уже используете токены OAuth или любое другое разрешение механизм, вы можете легко настроить API Gateway, чтобы не требовать подписанного API вызовы и просто пересылать заголовки токенов на ваш сервер для проверка.

Однако я не могу найти пример того, как это сделать в документации, и неясно, как получить доступ к этим данным с помощью Lambda.

Я могу настроить открытый API и получить доступ к объекту JSON, который является частью POST (Пошаговое руководство: шлюз API и функции лямбда-диска), но чтобы реализовать API стиля OAuth 2.0 с моим собственным провайдером, мне нужен доступ к заголовку "Авторизация".

Мое предпочтение заключается в том, чтобы установить это с помощью Lambda и Java 8, но пример использования node.js также будет полезен при понимании того, как это сделать.

Ответ 1

Вам нужно создать входное сопоставление внутри панели Integration Request на экране панели управления, описывающем ваш метод API.

Следующий код переводит name входной параметр запроса в Lambda Event input object:

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

Скриншот:

API Dashboard screenshot

Дополнительную информацию об этом можно найти в исходном API-шлюзе для входного потока Lambda на форумах AWS.

Ответ 2

Сначала вам нужно уловить заголовок Authorization из запроса HTTP GET. Затем вам нужно сопоставить это значение с объектом события Lambda.

Перейдите в панель инструментов API и нажмите "Запрос метода". Там вы можете добавить HTTP Request Header под названием Authorization, как показано ниже.

HTTP Request Headers

Это приведет к захвату заголовка Authorization, чтобы вы могли использовать его позже.

Теперь вернитесь к панели инструментов метода и нажмите Integration Request. Отсюда вы можете передать значение заголовка в функцию лямбда, используя такое сопоставление.

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

Теперь в вашей функции Lambda вы можете получить значение, подобное этому.

event.Authorization

Ответ 3

Вы можете использовать следующий шаблон сопоставления в запросе интеграции для общего отображения всех параметров пути, запроса и заголовка в событие Lambda. Вам все равно необходимо зарегистрировать их в разделе "Запрос метода" шлюза API, но вы можете по крайней мере отделить шаблон сопоставления от определенных параметров, которые вы хотите использовать. Таким образом, вам не нужно изменять код шаблона сопоставления каждый раз при изменении параметров заголовков, запросов или путей.

Я написал сообщение в блоге, которое дает более подробную информацию и некоторое объяснение шаблона сопоставления: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/

Вот шаблон сопоставления, который вы можете использовать:

{
  "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
  }  
}

Ответ 4

Пока это старый поток, я нашел, что лучше использовать интеграцию с лямбда-прокси для этой цели. С этим вам не нужно ничего настраивать в шлюзе API, и вы получаете все заголовки в своей лямбда-функции...

Ответ 5

В соответствии с настройкой ответа Prabhat с запросом интеграции лямбда-прокси - это самый простой способ сделать это, после чего вы можете получить доступ к заголовкам запроса, параметрам пути и параметрам запроса с помощью

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

Ответ 6

Решение от kennbrodhagen отлично сработало для меня, подробности смотрите в его ответе и блоге. Поскольку автор выражал предпочтение реализации Java, и мне потребовалось некоторое время, чтобы понять, как реализовать обработчик Kenn в Java, я просто делюсь Java-кодом, который соответствует:

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("{}");
    }
}

Ответ 7

Хотя это старый поток, я все еще получаю проблему при получении заголовка, queryParams, pathParams в функции Lambda.

Я создал простую лямбда-функцию в Python, как показано ниже

import json
def lambda_handler(event, context):  
    Body = {
        "response":{
           "resultStatus": "SUCCESS",
           "results":{
               "event": event
           }
        }
    }
    return {
        'statusCode': 200,
        'body': Body
    }

Я настроил то же самое с помощью API-шлюза с выбором по умолчанию и не вносил никаких изменений в шлюз.

Когда я бьюсь от супа или почтальона, используя метод get, получаю ответ только как

{
   "statusCode": 200,
   "body": {"response":    {
      "resultStatus": "SUCCESS",
      "results":       {
            "event": {}
      }
   }}
}

При попытке с пост-методами получить ответ как

{
   "statusCode": 200,
   "body": {"response":    {
      "resultStatus": "SUCCESS",
      "results":       {
            "event": {
            "Number1": 10,
            "Number2": 15}
      }
   }}
}

Числа 1 и 2 передаются как тело запроса json.

Я не могу получить любой заголовок, queryParams, pathParams. Нужно ли вносить какие-либо изменения в шлюз?

Ответ 8

@mojoken, глядя на приведенный вами пример, я вижу, что в этом случае вы используете функцию события для отображения всех заголовков.

logger.log("Заголовки:" + eventMap.get("Заголовки"));

Что делать, если я хотел получить конкретный заголовок, скажем, myheader. Как бы я это сделал?

Ответ 9

Это пример объекта события:

{
"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

}

Объект события содержит "headers", вы можете получить доступ к заголовкам запросов, отправленным на шлюз API, используя: event.headers.<header key>