使用无服务器框架请求验证
Posted
技术标签:
【中文标题】使用无服务器框架请求验证【英文标题】:Request validation using serverless framework 【发布时间】:2018-08-14 10:56:47 【问题描述】:我正在为后端使用无服务器框架。如何实现请求验证? (不想在 lambda 函数中编写验证)。
【问题讨论】:
【参考方案1】:要使用serverless
实现请求验证,您需要做几件事:
将您的模型/标头定义包含在您的堆栈中,然后告诉 API 网关使用它们进行请求验证。
您需要安装以下软件包:
serverless-aws-documentation
serverless-reqvalidator-plugin
然后您需要将它们包含在您的serverless.yml
中:
plugins:
- serverless-reqvalidator-plugin
- serverless-aws-documentation
注意:下面只是简要介绍如何合并这些软件包。访问包的文档页面以获取更全面的示例...
为 API 网关提供模型/标头描述。
您可以为模型导入 json 模式,并使用 serverless-aws-documentation
插件声明 http 标头。
以下是向serverless.yml
添加模型的方法:
custom:
documentation:
api:
info:
version: v0.0.0
title: Some API title
description: Some API description
models:
- name: SomeLambdaRequest
contentType: application/json
schema: $file(models/SomeLambdaRequest.json) # reference to your model's json schema file. You can also declare the model inline.
以下是在 lambda 定义中引用模型的方式:
functions:
someLambda:
handler: src/someLambda.handler
events:
- http:
# ... snip ...
documentation:
summary: some summary
description: some description
requestBody:
description: some description
requestModels:
application/json: SomeLambdaRequest
您还可以针对 lambda 定义声明请求标头,如下所示:
functions:
someLambda:
handler: src/someLambda.handler
events:
- http:
# ... snip ...
documentation:
summary: some summary
description: some description
requestHeaders:
- name: x-some-header
description: some header value
required: true # true or false
- name: x-another-header
description: some header value
required: false # true or false
告诉 API 网关实际使用模型进行验证
这部分使用了serverless-reqvalidator-plugin
包,您需要将AWS::ApiGateway::RequestValidator
资源添加到您的serverless.yml
文件中。
您可以指定是否要验证请求正文、请求标头或两者。
resources:
Resources:
onlyBody:
Type: AWS::ApiGateway::RequestValidator
Properties:
Name: 'only-body'
RestApiId:
Ref: ApiGatewayRestApi
ValidateRequestBody: true # true or false
ValidateRequestParameters: false # true or false
然后在个别功能上,您可以像这样使用验证器:
functions:
someLambda:
handler: src/someLambda.handler
events:
- http:
# ... snip ...
reqValidatorName: onlyBody # reference and use the 'only-body' request validator
将所有的 lambda 定义放在一起最终会看起来像这样:
functions:
someLambda:
handler: src/someLambda.handler
events:
- http:
# ... snip ...
reqValidatorName: onlyBody # reference and use the 'only-body' request validator
documentation:
summary: some summary
description: some description
requestBody:
description: some description
requestModels:
application/json: SomeLambdaRequest
requestHeaders:
- name: x-some-header
description: some header value
required: true # true or false
- name: x-another-header
description: some header value
required: false # true or false
【讨论】:
这有什么cmets吗?***.com/questions/54317704/…【参考方案2】:Serverless 框架现在支持,因此无需使用外部插件。
要启用请求验证,需要将以下内容添加到serverless.yml
:
HttpHandler:
handler: src/lambda/http/create.handler
events:
- http:
method: post
path: items
request:
schemas:
application/json: $file(models/create-todo-model.json)
除了将文件位置直接保留在application/json
下之外,您还可以在将模型名称定义在serverless.yml
文件的apiGateway
部分下之后保留它。 link to documentation
请注意,自 2022 年 2 月起,serverless-offline 插件不会验证您本地的 http.request.schemas
。尽管他们支持已弃用的版本http.request.schema
。
【讨论】:
你如何要求 content-type 是application/json?在此示例中,如果您不提供请求正文或提供不同的内容类型,则仍会调用 Lambda。 我也遇到了同样的问题。如果内容类型与application/json
不同,仍会调用 Lambda。有没有办法将 AWS API 网关配置为只允许 application/json
, content-type ?
API Gateway Request Validation 建议您还不能使用默认的 Lambda-Proxies 集成正确强制执行内容类型验证。为了避免内容类型问题,您需要使用(在无服务器非默认情况下)Lambda integration 并使用“从不”作为 passThrough 行为(如果您未指定任何内容,这是默认设置)。然后,这将阻止提供的设置未定义的内容类型。
我仍然更喜欢接受的答案,因为您可以定义 OpenApi 文档以及请求验证。
我们如何验证查询字符串参数?【参考方案3】:
正如 Ivan 所说,不需要外部插件,因为无服务器框架支持。但是,我认为配置它的方式已经改变。
functions:
create:
handler: posts.create
events:
- http:
path: posts/create
method: post
request:
schema:
application/json: $file(create_request.json)
这个例子取自: https://www.serverless.com/framework/docs/providers/aws/events/apigateway/#request-schema-validators
【讨论】:
NOTE: schema validators are only applied to content types you specify. Other content types are not blocked.
【参考方案4】:
如果您像我一样不想按照“https://***.com/questions/49133294/request-validation-using-serverless-framework”中的建议添加插件。
如果您根据需要设置参数并希望对其进行验证,则必须将请求验证器添加到您的 serverless.yml
Resources:
ParameterRequestValidator:
Type: AWS::ApiGateway::RequestValidator
Properties:
Name: ParameterRequestValidator
RestApiId:
Ref: ApiGatewayRestApi
ValidateRequestBody: false
ValidateRequestParameters: true
ApiGatewayMethodNameOfYourApiLookItUpInYourTemplate:
Properties:
RequestValidatorId:
Ref: ParameterRequestValidator
您要验证的方法将被命名为ApiGateway<Method><Get | Post | Patch | Put | Delete >:
。您可以在将无服务器函数打包到创建的模板文件中时查找名称。
感谢https://github.com/serverless/serverless/issues/5034#issuecomment-581832806https://github.com/serverless/serverless/issues/5034#issuecomment-581832806
【讨论】:
我在尝试上述操作时收到此错误:发生错误:ApiGatewayResourceResourceDashdata - 遇到不支持的属性 RequestValidatorId。 请确保您的资源名称正确。另请参阅有关此答案的 cmets ***.com/a/61798760/5493813 @ShwetaJ 如果您觉得答案对您有帮助,请为答案投票【参考方案5】:使用无服务器请求验证
plugins:
- serverless-python-requirements
- serverless-wsgi
- serverless-reqvalidator-plugin
- serverless-aws-documentation
provider:
name: aws
runtime: python3.8
region: us-east-1
functions:
hello:
handler: handler.hello
events:
- http:
path: /
method: get
likes:
handler: handler.likes
events:
- http:
path: /likes
method: get
integration: lambda
reqValidatorName: xMyRequestValidator
request:
passThrough: NEVER
parameters:
querystrings:
userid: true
activityid: true
template:
application/json: ' "userid":"$input.params(''userid'')","activityid":"$input.params(''activityid'')"'
response:
headers:
Content-Type: "'application/json'"
custom:
wsgi:
app: handler.app
pythonBin: python # Some systems with Python3 may require this
packRequirements: false
pythonRequirements:
dockerizePip: non-linux
resources:
Resources:
xMyRequestValidator:
Type: "AWS::ApiGateway::RequestValidator"
Properties:
Name: 'my-req-validator'
RestApiId:
Ref: ApiGatewayRestApi
ValidateRequestBody: true
ValidateRequestParameters: true
【讨论】:
以上是关于使用无服务器框架请求验证的主要内容,如果未能解决你的问题,请参考以下文章
使用 Symfony 框架在生产服务器上的用户登录失败(身份验证请求无法处理,因为...)
使用Symfony框架在生产服务器上登录失败(由于...无法处理身份验证请求)
无服务器框架 + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = 无法使 POST 请求工作
无服务器框架+ AWS + Lambda + DynamoDB + GraphQL + Apollo Server =无法使POST请求工作