Как получить доступ к заголовкам HTTP для запроса к AWS API Gateway с помощью Lambda?
В FAQ по шлюзу API я вижу, что можно получить доступ к заголовкам запросов, отправленных на шлюз API...
Если вы уже используете токены OAuth или какой-либо другой механизм авторизации, вы можете легко настроить API-шлюз, чтобы он не требовал подписанных вызовов API, и просто перенаправить заголовки токенов в бэкэнд для проверки.
Тем не менее, я не могу найти пример того, как это сделать в документации, и неясно, как получить доступ к этим данным с помощью Lambda.
Я могу настроить открытый API и получить доступ к объекту JSON, который является частью POST ( Walkthrough: API Gateway и Lambda Functions), но для реализации API стиля OAuth 2.0 с моим собственным поставщиком мне нужен доступ к заголовок "Авторизация".
Я предпочитаю настроить это с помощью Lambda и Java 8, но пример с использованием node.js также поможет понять, как этого добиться.
8 ответов
Вам нужно создать входное отображение внутри Integration Request
панель на экране панели с описанием вашего метода API.
Следующий код переводит name
входной параметр запроса в Lambda Event input object
:
{
"name": "$input.params('name')"
}
Скриншот:
Дополнительную информацию об этом можно найти в исходной теме ввода от шлюза API к лямбде на форумах AWS.
Вы можете использовать следующий шаблон сопоставления в запросе на интеграцию для общего сопоставления всех параметров пути, запроса и заголовка с событием 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
}
}
Во-первых, вам нужно поймать Authorization
заголовок из HTTP-запроса GET. Затем вам нужно отобразить это значение на объект события Lambda.
Перейдите на панель инструментов метода API и нажмите "Запрос метода". Там вы можете добавить HTTP Request Header
называется Authorization
как показано ниже.
Это поймает Authorization
заголовок, чтобы вы могли использовать его позже.
Теперь вернитесь на панель методов и нажмите Integration Request
, Отсюда вы можете передать значение заголовка в функцию Lambda, используя такое отображение.
{
"Authorization": "$input.params('Authorization')"
}
Теперь в вашей лямбда-функции вы можете получить такое значение.
event.Authorization
Хотя это старая ветка, я считаю, что для этой цели лучше всего использовать лямбда-прокси-интеграцию. При этом вам не нужно ничего настраивать в шлюзе API, и вы получаете все заголовки в вашей лямбда-функции...
Согласно ответу Прабхата, настройка лямбда-прокси-запроса на интеграцию является самым простым способом сделать это, после чего вы можете получить доступ к заголовкам запроса, параметрам пути и параметрам запроса через
event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
Это пример объекта события:
{
"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>
Решение от kennbrodhagen отлично сработало для меня, подробности смотрите в его ответе и блоге. Поскольку автор выражал предпочтение реализации Java, и мне потребовалось некоторое время, чтобы понять, как реализовать обработчик Кенна в 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("{}");
}
}
Для .Net Core 3.1+
Если вы включили интеграцию Lambda Proxy, вам просто нужно проверитьHeaders
коллекция в вашем обработчике Lambda:
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest data, ILambdaContext context)
{
if (data.Headers.ContainsKey("x-api-key"))
{
...
}