基于SAM模板开发AWS应用,如何为含自定义Lambda授权器的方法添加映射模板?
我来帮你搞定这个问题——在SAM模板或者Swagger 2.0里配置API Gateway映射模板其实有很明确的方法,而且结合你已经设置的自定义Lambda授权器,还能把授权上下文数据也映射进去。下面分两种场景详细说明:
在SAM模板中添加API Gateway映射模板
你可以通过两种方式在SAM里配置映射模板:直接定义AWS::ApiGateway::Method资源,或者在AWS::Serverless::Function的Events中关联API时配置。
方式1:通过AWS::ApiGateway::Method配置
这种方式适合需要精细控制API方法的场景,结合自定义授权器的示例如下:
Resources: # 先定义API和自定义授权器 MyServerlessApi: Type: AWS::Serverless::Api Properties: StageName: Prod Auth: DefaultAuthorizer: MyCustomAuth Authorizers: MyCustomAuth: FunctionArn: !GetAtt MyAuthLambdaFunction.Arn Identity: Header: Authorization # 定义具体的API方法并配置映射模板 MyProtectedMethod: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref MyServerlessApi ResourceId: !GetAtt MyServerlessApi.RootResourceId HttpMethod: POST AuthorizationType: CUSTOM AuthorizerId: !Ref MyCustomAuth Integration: Type: AWS_PROXY IntegrationHttpMethod: POST Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyBusinessLambda.Arn}/invocations # 请求映射模板:可以把授权上下文、请求ID等数据传给后端Lambda RequestTemplates: application/json: | { "requestBody": $input.json('$'), "userId": "$context.authorizer.userId", "requestId": "$context.requestId" } # 响应映射模板:格式化后端返回的响应 ResponseTemplates: application/json: | #set($response = $input.path('$')) { "status": "success", "data": $response.body, "traceId": "$context.requestId" }
方式2:在AWS::Serverless::Function的Events中配置
如果你的API是和Lambda函数直接关联定义的,可以直接在Events节点下添加映射模板:
MyBusinessLambda: Type: AWS::Serverless::Function Properties: CodeUri: src/ Handler: index.handler Runtime: nodejs18.x Events: ProtectedApiEvent: Type: Api Properties: RestApiId: !Ref MyServerlessApi Path: /protected-endpoint Method: POST Auth: Authorizer: MyCustomAuth # 直接在这里配置请求映射模板 RequestTemplates: application/json: | { "user": "$context.authorizer.userInfo", "payload": $input.json('$') }
在Swagger 2.0中添加映射模板
如果你用Swagger来定义API,可以在x-amazon-apigateway-integration扩展字段中配置requestTemplates和responseTemplates,同时关联自定义授权器:
swagger: "2.0" info: title: MyProtectedApi version: "1.0" paths: /protected-endpoint: post: # 关联自定义授权器 security: - MyCustomAuth: [] x-amazon-apigateway-integration: type: aws_proxy uri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:MyBusinessLambda/invocations" httpMethod: POST # 请求映射模板 requestTemplates: application/json: | { "body": $input.json('$'), "authorizerData": "$context.authorizer" } # 响应映射模板 responseTemplates: application/json: | #set($root = $input.path('$')) { "statusCode": $root.statusCode, "message": "$root.body.message" } responses: {} # 定义自定义授权器的Security Definition securityDefinitions: MyCustomAuth: type: apiKey name: Authorization in: header x-amazon-apigateway-authtype: custom x-amazon-apigateway-authorizer: type: token authorizerUri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:MyAuthLambda/invocations"
关于“未找到可用模板”的排查提示
如果你在配置时找不到可用模板的选项,可能是这几个原因:
- 确保你是针对具体的API方法配置模板,而不是在API的全局层级;
- 确认映射模板绑定了正确的Content-Type(比如
application/json、application/x-www-form-urlencoded),API Gateway只会匹配请求头中对应的Content-Type模板; - 如果使用的是
AWS_PROXY集成,虽然默认会透传请求,但仍然可以通过RequestTemplates来修改请求格式,不要误以为这种集成不支持模板;
内容的提问来源于stack exchange,提问作者Pathikrit Sanyal
相关产品推荐
相关产品推荐

