49

我在API Gateway 常见问题解答中看到可以访问发送到 API Gateway 的请求标头...

如果您已经使用 OAuth 令牌或任何其他授权机制,您可以轻松设置 API Gateway 不需要签名的 API 调用,只需将令牌标头转发到您的后端进行验证。

但是,我在文档中找不到如何执行此操作的示例,也不清楚如何使用 Lambda 访问这些数据。

我能够设置一个开放的 API 并获得对作为 POST 一部分的 JSON 对象的访问权(演练:API 网关和 Lambda 函数),但是为了使用我自己的提供程序实现 OAuth 2.0 风格的 API,我需要访问“授权”标头。

我的偏好是使用 Lambda 和 Java 8 进行设置,但使用 node.js 的示例也有助于理解如何完成此操作。

4

7 回答 7

37

您可以在集成请求中使用以下映射模板将所有路径、查询和标头参数一般映射到 Lambda 事件中。您仍然需要在 API Gateway 的方法请求部分中注册它们,但您至少可以将映射模板与您要使用的特定参数分离。这样您就不必在每次更改标题、查询或路径参数时更改映射模板代码。

我写了一篇博客文章,提供了更多详细信息和映射模板的一些解释:http: //kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event -来自-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
  }  
}
于 2015-11-09T03:31:45.173 回答
36

首先,您需要捕获Authorization来自 HTTP GET 请求的标头。然后您需要将该值映射到 Lambda 事件对象。

转到 API 方法仪表板并单击方法请求。在那里,您可以添加一个HTTP Request Header调用Authorization,如下所示。

HTTP 请求标头

这将捕获Authorization标题,以便您以后可以使用它。

现在返回方法仪表板并单击Integration Request。从这里,您可以使用这样的映射将标头的值传递给 Lambda 函数。

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

现在在您的 Lambda 函数中,您可以获得这样的值。

event.Authorization
于 2015-07-13T04:35:10.847 回答
23

您需要Integration Request在仪表板屏幕上的面板内创建描述您的 API 方法的输入映射。

以下代码将name查询输入参数转换为Lambda Event input object

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

截屏:

API 仪表板屏幕截图

您可以在 AWS 论坛上的原始 API Gateway 到 Lambda 输入线程中找到更多信息。

于 2015-07-12T20:46:00.677 回答
14

虽然这是一个旧线程,但我发现最好使用 lambda 代理集成。有了这个,您不必在 API 网关中配置任何东西,并且您可以在 lambda 函数中获得所有标头...

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

于 2017-05-07T11:30:28.810 回答
2

根据 Prabhat 的回答,使用 lambda 代理集成请求设置是最简单的方法,之后您可以通过以下方式访问请求标头、路径参数和查询参数

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
于 2017-09-08T10:43:23.997 回答
1

这是一个示例事件对象:

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

于 2019-10-18T12:57:20.907 回答
0

kennbrodhagen 的解决方案对我很有用,有关详细信息,请参阅他的答案和博客。由于发帖人表达了对 Java 实现的偏好,并且我花了一段时间才弄清楚如何在 java 中实现 Kenn 的处理程序,所以我只是分享对应的 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("{}");
    }
}
于 2018-10-31T15:45:29.080 回答