【问题标题】:Request validation using serverless framework使用无服务器框架请求验证
【发布时间】:2018-08-14 10:56:47
【问题描述】:

我正在为后端使用无服务器框架。如何实现请求验证? (不想在 lambda 函数中编写验证)。

【问题讨论】:

    标签: amazon-web-services validation aws-lambda aws-api-gateway serverless-framework


    【解决方案1】:

    要使用serverless 实现请求验证,您需要做几件事: 将您的模型/标头定义包含在您的堆栈中,然后告诉 API 网关使用它们进行请求验证。

    您需要安装以下软件包:

    然后您需要将它们包含在您的serverless.yml 中:

    plugins:
      - serverless-reqvalidator-plugin
      - serverless-aws-documentation
    

    注意:下面只是简要介绍如何合并这些软件包。访问包的文档页面以获取更全面的示例...

    1. 为 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
      
    2. 告诉 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
    

    【讨论】:

    【解决方案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://stackoverflow.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 stackoverflow.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 
    

    【讨论】:

      猜你喜欢
      • 2020-10-09
      • 2021-11-25
      • 1970-01-01
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 2019-01-27
      • 2015-10-19
      • 2019-08-24
      相关资源
      最近更新 更多