API Gateway 验证内容类型标头
Posted
技术标签:
【中文标题】API Gateway 验证内容类型标头【英文标题】:API Gateway validate content-type header 【发布时间】:2019-02-24 23:07:31 【问题描述】:如果内容类型不是 json api 网关不进行验证,只是通过。我使用代理集成,所以没有映射模板,只能使用“when_no_match”。我正在使用内联招摇。
我可以检查标头是否存在但不检查值 - 我该怎么做?
/myMethod:
post:
x-amazon-apigateway-request-validator : "myvalidator"
parameters:
# How do I also validate Content-Type value is "application/json"
- name: Content-Type
in: header
required: true
我希望 API 网关对此进行验证,因此我不必在代码中检查它
【问题讨论】:
您希望响应始终使用 application/json 吗? 我希望 API Gateway 拒绝对此方法的未将 content-type 设置为 application/json 的请求 您可以使用 Lambda@edge 轻松拒绝没有正确内容类型的请求。此外,这将比 API GW 中的更改更易于维护。 【参考方案1】:转到端点的Integration Request
选项卡,单击Mapping Templates
,将Request body passthrough
设置为never
,为application/javascript
添加映射模板,然后从Generate template
旁边的下拉列表中单击Method Request Passthrough
.
这是招摇的 sn-p:
requestTemplates:
application/json: |
## See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
## This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
#set($allParams = $input.params())
"body-json" : $input.json('$'),
"params" :
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" :
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
#if($foreach.hasNext),#end
#end
,
"stage-variables" :
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
#if($foreach.hasNext),#end
#end
,
"context" :
"account-id" : "$context.identity.accountId",
"api-id" : "$context.apiId",
"api-key" : "$context.identity.apiKey",
"authorizer-principal-id" : "$context.authorizer.principalId",
"caller" : "$context.identity.caller",
"cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
"cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
"cognito-identity-id" : "$context.identity.cognitoIdentityId",
"cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
"http-method" : "$context.httpMethod",
"stage" : "$context.stage",
"source-ip" : "$context.identity.sourceIp",
"user" : "$context.identity.user",
"user-agent" : "$context.identity.userAgent",
"user-arn" : "$context.identity.userArn",
"request-id" : "$context.requestId",
"resource-id" : "$context.resourceId",
"resource-path" : "$context.resourcePath"
passthroughBehavior: "never"
httpMethod: "POST"
type: "aws"
【讨论】:
Mapping Templates
部分在使用代理集成时不可用。目前似乎没有办法通过代理集成拒绝基于标头值的请求。【参考方案2】:
因为我自己也在这么长时间后寻找答案,所以我发现涉及 swagger/openapi 规范文件的唯一解决方案是使用这个映射模板(这是我能想到的最短的):
#set($allParams = $input.params())
"body" : $input.json('$'),
#set($pathParams = $allParams.get('path'))
"pathParameters" :
#foreach($paramName in $pathParams.keySet())
"$paramName" : "$util.escapeJavaScript($pathParams.get($paramName))"
#if($foreach.hasNext),#end
#end
,
#set($queryParams = $allParams.get('querystring'))
"queryString" :
#foreach($paramName in $queryParams.keySet())
"$paramName" : "$util.escapeJavaScript($queryParams.get($paramName))"
#if($foreach.hasNext),#end
#end
在我们想要应用它的规范路径中:
paths:
/your-path:
x-amazon-apigateway-integration:
credentials: "arn:aws:iam::xxx:role/yyy"
uri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:zzz:function:qqq/invocations"
responses:
default:
statusCode: 200
passthroughBehavior: never
httpMethod: POST
requestTemplates:
application/json: "#set($allParams = $input.params())\n \n \
\ \"body\" : $input.json('$'),\n #set($pathParams = $allParams.get('path'))\n\
\ \"pathParameters\" : \n #foreach($paramName\
\ in $pathParams.keySet())\n \"$paramName\" : \"$util.escapeJavaScript($pathParams.get($paramName))\"\
\n #if($foreach.hasNext),#end\n #end\n\
\ ,\n #set($queryParams = $allParams.get('querystring'))\n\
\ \"queryString\" : \n #foreach($paramName\
\ in $queryParams.keySet())\n \"$paramName\" : \"$util.escapeJavaScript($queryParams.get($paramName))\"\
\n #if($foreach.hasNext),#end\n #end\n\
\ \n "
type: aws
不幸的是,这对我来说非常笨拙,我只是决定使用标准代理集成,并将请求验证设置为全部:
x-amazon-apigateway-request-validators:
all:
validateRequestBody: true,
validateRequestParameters: true
x-amazon-apigateway-request-validator: all
【讨论】:
以上是关于API Gateway 验证内容类型标头的主要内容,如果未能解决你的问题,请参考以下文章
具有 Cognito 身份验证的 AWS API Gateway Lambda 函数返回 415 Unsupported Media Type