当前位置: 首页 > 知识库问答 >
问题:

将 Swagger API 验证与无服务器框架结合使用

尚安平
2023-03-14

我想向无服务器 aws 节点模板添加 api 验证,到目前为止,我测试过的任何内容都运行良好。

我目前的方法是用包含我的验证模型的yml/json swagger定义覆盖现有的api-gateway,它是由无服务器框架生成的。当我在API-Gateway UI中测试它时,这对我来说是有效的,但是对于外部请求,API不会验证lambda-proxy的请求。

当我使用普通lambda时,api网关也不经过验证或转换就通过请求体。

我当前带有验证的swagger api定义:

  swagger: "2.0"
  info:
    title: feedback
    version: '1.0'

  schemes:
  - https
  produces:
  - application/json
  x-amazon-apigateway-api-key-source : HEADER

  x-amazon-apigateway-request-validators:
    full:
      validateRequestBody: true
      validateRequestParameters: true
    body-only:
      validateRequestBody: true
      validateRequestParameters: false
  x-amazon-apigateway-request-validator: full

  # Custom 400 response with validation feedback
  x-amazon-apigateway-gateway-responses:
    BAD_REQUEST_BODY:
      statusCode: 400
      type:
        application/json: 
      responseTemplates:
      application/json:
        |-
          {
              "message": $context.error.messageString,
              "validation":  "$context.error.validationErrorString",
              "statusCode": "'400'"
          }

  # request structure
  paths:
    /feedback:
      post:
        # validation definition
        x-amazon-apigateway-request-validator: body-only
        parameters:
        - in: body
          name: Create ...
          required: true
          schema: 
            "$ref": "#/definitions/Model"
        responses:
          '200':
            description: validation succeeded
          '400':
            description: validation failed

        x-amazon-apigateway-integration:

          uri: "arn:aws:apigateway:{api-region}:lambda:path/2015-03-31/functions/arn:aws:lambda:{lambda-region}:{konto-id}:function:{function-name}/invocations"

          passthroughBehavior: when_no_match
          httpMethod: POST
          requestTemplates:
            application/json: '{"statusCode": 200}'
          type: aws
      get:
        responses:
          '201':
            description: list all Data
            content:
              application/json:
                schema:
                  type: array
                  items:
                    feedback:
                      $ref: "#/definitions/Model"
          '401':
            $ref: "#/definitions/UnauthorizedError"
        x-amazon-apigateway-integration:
          uri: "arn:aws:apigateway:{api-region}:lambda:path/2015-03-31/functions/arn:aws:lambda:{lambda-region}:{konto-id}:function:{function-name}/invocations"
          passthroughBehavior: never
          httpMethod: POST
          type: aws_proxy

  # definition of the request/respons model with validation
  definitions:
      Model:
        type: object
        properties:
          topic:
            $ref: "#/definitions/Topic"
          text:
            type: string
            minLength: 1
            maxLength: 250
        required:
          - topic
          - text
      Topic:
            type: string
            enum: 
              - xyz

my serverless.yml中的api定义

functions:
  create:
    handler: feedback/create.create
    events:
     - http:
         path: feedback
         method: post
 list:
    handler: feedback/list.list
    events:
      - http:
          path: feedback
          method: get 

lambda函数只从DynamoDB读取/写入反馈

有人知道如何在不使用小插件(serverless-reqvalidator-plugin)的情况下将某种api验证添加到我的无服务器项目中,或者如何解决数据转换的问题吗?

共有1个答案

席波娃
2023-03-14

好的,验证适用于内部测试但不适用于外部请求的问题的解决方案非常明显。我忘记部署新的api定义了。

aws apigateway create-deployment --rest-api-id {api-id} --stage-name dev

此外,我还更改了我的API定义。我现在将一个普通的lambda嵌入到我的Post请求中。这是唯一的方法,我可以确保只有json内容得到验证,然后传递给lamda函数。因为我没有使用lambda代理,请求事件会从api网关转换,所以我必须定义一个请求模板,将整个请求正文放入一个新请求中。

 requestTemplates:
      application/json: '{"statusCode": 202, "body": $input.body}'

通过这种方式,我还使用 Cors 标头在预定义的 api 响应中转换了 lambda 响应。

我最终的解决方案是:

1:编写一个swagger api定义:

  swagger: "2.0"
  info:
    title: xxxxxx
    version: '0.0.0'

  schemes:
  - https
  produces:
  - application/json

  x-amazon-apigateway-api-key-source : HEADER

  # Define which parts of the request should be validated
  x-amazon-apigateway-request-validators:
    full:
      validateRequestBody: true
      validateRequestParameters: true
    body-only:
      validateRequestBody: true
      validateRequestParameters: false

  # Custom response model from the api-gateway that return validation error string 
  x-amazon-apigateway-gateway-responses:
    BAD_REQUEST_BODY:
      statusCode: 400
      type:
        application/json:
      responseParameters: # CORS Headers
          gatewayresponse.header.Access-Control-Allow-Credentials : "'true'"
          gatewayresponse.header.Access-Control-Allow-Origin : "'*'"
      responseTemplates:
      application/json: #must be an json string because otherwiese there are some transformation issues
        |-
          {
              "message": $context.error.messageString,
              "validation":  "$context.error.validationErrorString",
              "statusCode": "400"
          }   


  paths:
    /feedback:
      options: 
        description:
          Enable CORS by returning correct headers
        tags:
          - CORS
        x-amazon-apigateway-integration:
          type: mock
          requestTemplates:
            application/json: |
              {
                "statusCode" : 200
              }
          responses:
            "default":
              statusCode: "200"
              responseParameters: # CORS Headers
                method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
                method.response.header.Access-Control-Allow-Methods : "'*'"
                method.response.header.Access-Control-Allow-Origin : "'*'"
              responseTemplates:
                application/json: |
                  {}
        responses:
          200:
            description: Default response for CORS method
            headers:
              Access-Control-Allow-Headers:
                type: "string"
              Access-Control-Allow-Methods:
                type: "string"
              Access-Control-Allow-Origin:
                type: "string"
      post:
        # validation definition
        x-amazon-apigateway-request-validator: body-only
        parameters:
        - in: body 
          name: requestBody
          required: true
          content:
            application/json:
          schema: # validation model
            "$ref": "#/definitions/Model"
        responses: # response documentation
          '200':
            description: Create ......
            headers: # Header format for the CORS headers
              Access-Control-Allow-Credentials:
                type: "string"
              Access-Control-Allow-Origin:
                type: "string"
        x-amazon-apigateway-integration:
          responses:
            default:
              statusCode: "200"
              responseParameters: # CORS Header
                method.response.header.Access-Control-Allow-Credentials : "'true'"
                method.response.header.Access-Control-Allow-Origin : "'*'"
          uri: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::account-id}:function:{AWS::lambda-function-name}/invocations
          requestTemplates:
            application/json: '{"statusCode": 202, "body": $input.body}' 
          passthroughBehavior: never # only accept Json Data
          httpMethod: POST 
          type: aws 

      get:
        security: # X-API-Key
          - authorizer: [] 
        responses: 
          '200':
            description: ......
        x-amazon-apigateway-integration: 
          uri: "arn:aws:apigateway:xxx:lambda:path/2015-03-31/functions/arn:aws:lambda:xxx:xxxxxxx:function:function-name/invocations"
          httpMethod: POST
          type: aws_proxy 

  definitions:
    Model:
       # Swagger Model with validation

  securityDefinitions:
    authorizer :
      type : apiKey                         
      name : x-api-key                 
      in : header                           

2:覆盖现有的无服务器api:

aws apigateway put-rest-api --rest-api-id {api-id} --mode overwrite --body file://xxxx/api.yml

3: 不要忘记部署新的api:

aws apigateway create-deployment --rest-api-id {api-id} --region eu-central-1 --stage-name ...
 类似资料:
  • 如您所见,我正在使用codePipeline和codeBuild自动化部署。我的后端基于无服务器框架,它在触发命令时部署lambda函数。这就是我没有使用codeDeploy进行传统部署的原因<代码>构建规范。yml文件如下所示: 现在,我有3个关于CodeBuild和Serverless的问题: 问题1:命令依赖于一个名为的文件,其中包含数据库密码等秘密。此文件将不会被签入git。你认为在cod

  • 我正在使用预装的Visual Studio解决方案开发我的首批OAuth解决方案之一。 不过,同时我也希望我的服务器应用程序拥有“完全访问权限”。他们需要能够获得列表增加多个用户,删除东西等等。 下面是我的问题,我认为这些问题可以很容易地一起回答: 如何管理两个短期令牌(承载令牌?)连同永久令牌(API令牌?) 我在访问级别上有何不同,因此某些方法需要永久令牌? 在同一方法中,我在访问级别上有何不

  • 我在没有nat网关/互联网接入的vpc中部署了一些功能。目标:通过SES从该功能发送电子邮件(在vpc中) 我已经尝试使用公共私有子网与nat网关发送电子邮件,它工作正常。但是我正在尝试使用它vi VPCendpoint。我已经创建了一个电子邮件vpcendpoint,但不确定如何配置它在serverless.yml.已经尝试设置配置如 中所述https://www.serverless.com/

  • 使用GatewayWorker时开发者最关心的是如何与现有mvc框架(ThinkPHP Yii laravel等)整合,以下是官方推荐的整合方式。见示意图: 总体原则: 现有mvc框架项目与GatewayWorker独立部署互不干扰 所有的业务逻辑都由网站页面post/get到mvc框架中完成 GatewayWorker不接受客户端发来的数据,即GatewayWorker不处理任何业务逻辑,Gat

  • 所以我试图让Hibernate Validator注释处理器在Kotlin项目中工作,来检查我的JSR 380注释,运气不太好。 不幸的是,文档中没有提到如何用Gradle设置它,很明显,对于Kotlin,我们必须使用“Kapt”来启用java注释处理器。 Hibernate验证器注释处理器文档:http://docs.jboss.org/hibernate/stable/validator/re

  • 我试图集成django验证器1.9与django rest框架序列化器。但是序列化的用户(django rest框架)与django验证器不兼容。 下面是序列化程序。派克 我设法使MinimumLengthValidator和NumericPasswordValidator正确,因为这两个函数validate在验证时都不使用“user”。源代码在这里 摘自django源代码: 对于其他验证器,如U