我正在使用无服务器框架搭建后端。我该如何实现请求验证?(不想在 lambda 函数内编写验证逻辑)。
我正在使用无服务器框架搭建后端。我该如何实现请求验证?(不想在 lambda 函数内编写验证逻辑)。
现在,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
部分下。 文档链接
需要注意的是:截至2022年2月,serverless-offline插件不会在本地验证http.request.schemas
,尽管它们支持已弃用的版本http.request.schema
。
要使用serverless
实现请求验证,您需要执行以下操作:
在您的堆栈中包含您的模型/标题定义,然后告诉API网关将它们用于请求验证。
您需要安装以下软件包:
然后您需要将它们包含在您的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
包,您需要在serverless.yml
文件中添加AWS::ApiGateway::RequestValidator
资源。
您可以指定是否要验证请求体、请求头或两者都要验证。
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
正如Ivan所提到的,由于Serverless框架已支持此功能,因此无需使用外部插件。然而,我认为配置方式已经发生了变化。
functions:
create:
handler: posts.create
events:
- http:
path: posts/create
method: post
request:
schema:
application/json: ${file(create_request.json)}
schemas
,而不是schema
。 - Bersan如果你和我一样,不想像"https://dev59.com/F1UM5IYBdhLWcg3wOeTz"中建议的那样添加插件。
如果你设置了必需参数并且想要验证它们,你必须在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 >
。您可以在创建模板文件时查找该名称。使用无服务器进行请求验证
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
application/json
,Lambda 仍然会被调用。有没有办法配置 AWS API 网关只允许application/json
的 content-type? - nithin