日期: 2022年4月20日

  • 在 Laravel 6、Module、Lighthouse 中实现 安全 验证 的流程(使用 @rules 指令,使用 Exists 规则)

    在 Laravel 6、Module、Lighthouse 中实现 安全 验证 的流程(使用 @rules 指令,使用 Exists 规则)

    1、当请求响应成功时的结构。如图1
    当请求响应成功时的结构
    图1
    
    
    
    mutation {
      onlineStoreThemePreviewCodeGenerate(themeId: "vogue") {
        themePreviewCode
      }
    }
    
    
    
    
    
    
    {
      "data": {
        "onlineStoreThemePreviewCodeGenerate": {
          "themePreviewCode": "eyJpdiI6IjZlZ3RpZzlyZmp6S3BzQWJcL0N1NVR3PT0iLCJ2YWx1ZSI6IkNGdVwvdGJMZFI2MWJPRXFMbTNhdmVOUVVCVDhzb1ZnSzFNQzd2Y1RoSElGMmw4VkxOWFppbnlNbmtjaFNnbG9FXC9Oa1hYSndRU1hlcmpFMktneFNkQmVoMjhENnoxb3dQY0lxNHZnemJrNXlLTlpNKzJmbEU4RTFXNnFza2dyVG4iLCJtYWMiOiI0NzcwZjllYjIxZDliOGFkMTU2OTdiZmVmYWViN2I2OTI5NWE0ZDFjOTBmOGU1MGMyZjI3MzBjNTQxMWE3ODQ2In0="
        }
      }
    }
    
    
    
    2、但是,现阶段并未针对请求参数进行安全验证。参考:https://lighthouse-php.com/master/security/validation.html#single-arguments 。Lighthouse 允许您在查询和变更中使用 Laravel 的验证。 3、此 GraphQL API 的变更仅有一个请求参数,即 themeId,仅需要验证此字段是否在表中存在即可。 4、利用内置验证规则的最简单方法是使用 @rules 指令。使用 Exists 规则
    
    
    extend type Mutation {
        "生成主题预览代码"
        onlineStoreThemePreviewCodeGenerate(themeId: ID! @rules(apply: ["exists:theme_asset,theme_id"])): OnlineStoreThemePreviewCodeGeneratePayload @field(resolver: "Modules\\ThemeStore\\Resolver\\ThemePreview\\GenerateThemePreviewCodeResolver")
    }
    
    
    
    5、测试验证规则是否有效,确定有效。如图2
    测试验证规则是否有效,确定有效
    图2
    
    
    
    mutation {
      onlineStoreThemePreviewCodeGenerate(themeId: "vogue1") {
        themePreviewCode
      }
    }
    
    
    
    
    
    
    {
      "errors": [
        {
          "message": "Validation failed for the field [onlineStoreThemePreviewCodeGenerate].",
          "extensions": {
            "validation": {
              "themeId": [
                "The selected theme id is invalid."
              ]
            },
            "category": "validation"
          },
          "locations": [
            {
              "line": 2,
              "column": 3
            }
          ],
          "path": [
            "onlineStoreThemePreviewCodeGenerate"
          ],
          "trace": ...
        }
      ],
      "data": {
        "onlineStoreThemePreviewCodeGenerate": null
      }
    }
    
    
    
    6、查看 Laravel Telescope 中请求中的 SQL 语句。
    
    
    select
      count(*) as aggregate
    from
      `theme_asset`
    where
      `theme_id` = 'vogue1'
    
    
    
    7、但是,现阶段还存在一个问题,因为表名称的前缀恰好是 ”,如果设置为 ‘object_’,可能会有问题。再次请求,发现报错,符合预期。说明验证规则中会自动读取表前缀的。无需要调整。如图3
    但是,现阶段还存在一个问题,因为表名称的前缀恰好是 '',如果设置为 'object_',可能会有问题。再次请求,发现报错,符合预期。说明验证规则中会自动读取表前缀的。无需要调整
    图3
    
    
            'mysql' => [
                ...
                'prefix' => 'object_',
            ],
    
    
    
    
    
    {
      "errors": [
        {
          "debugMessage": "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'object_store.object_theme_asset' doesn't exist (SQL: select count(*) as aggregate from `object_theme_asset` where `theme_id` = vogue1)",
          "message": "Internal server error",
          "extensions": {
            "category": "internal"
          },
          "locations": [
            {
              "line": 2,
              "column": 3
            }
          ],
          "path": [
            "onlineStoreThemePreviewCodeGenerate"
          ],
          "trace": [
            ...
          ]
        }
      ],
      "data": {
        "onlineStoreThemePreviewCodeGenerate": null
      }
    }