From 41d1f8cbc32bde2b8b10534e134765fae17399cf Mon Sep 17 00:00:00 2001 From: traky Date: Tue, 24 Dec 2024 14:24:37 +0800 Subject: [PATCH] improve docs --- docs/en/latest/plugins/request-validation.md | 572 +++++++++++++------ docs/zh/latest/plugins/request-validation.md | 566 ++++++++++++------ 2 files changed, 793 insertions(+), 345 deletions(-) diff --git a/docs/en/latest/plugins/request-validation.md b/docs/en/latest/plugins/request-validation.md index 54f4eef491e6..69c28b6d4bf2 100644 --- a/docs/en/latest/plugins/request-validation.md +++ b/docs/en/latest/plugins/request-validation.md @@ -4,7 +4,7 @@ keywords: - Apache APISIX - API Gateway - Request Validation -description: This document describes the information about the Apache APISIX request-validation Plugin, you can use it to validate the requests before forwarding them to an Upstream service. +description: The request-validation Plugin validates requests before forwarding them to Upstream services. This Plugin uses JSON Schema for validation and can validate headers and body of a request. --- + + + + ## Description -The `request-validation` Plugin can be used to validate the requests before forwarding them to an Upstream service. This Plugin uses [JSON Schema](https://github.com/api7/jsonschema) for validation and can be used to validate the headers and body of the request. +The `request-validation` Plugin validates requests before forwarding them to Upstream services. This Plugin uses [JSON Schema](https://github.com/api7/jsonschema) for validation and can validate headers and body of a request. + +See [JSON schema specification](https://json-schema.org/specification) to learn more about the syntax. ## Attributes @@ -36,8 +42,8 @@ The `request-validation` Plugin can be used to validate the requests before forw |---------------|---------|----------|---------|---------------|---------------------------------------------------| | header_schema | object | False | | | Schema for the request header data. | | body_schema | object | False | | | Schema for the request body data. | -| rejected_code | integer | False | 400 | [200,...,599] | Status code to show when the request is rejected. | -| rejected_msg | string | False | | | Message to show when the request is rejected. | +| rejected_code | integer | False | 400 | [200,...,599] | Status code to return when rejecting requests. | +| rejected_msg | string | False | | | Message to return when rejecting requests. | :::note @@ -45,11 +51,12 @@ At least one of `header_schema` or `body_schema` should be filled in. ::: -## Enable Plugin +## Examples -You can configure the Plugin on a specific Route as shown below: +The examples below demonstrate how you can configure `request-validation` for different scenarios. :::note + You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command: ```bash @@ -58,255 +65,464 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"/ ::: +### Validate Request Header + +The following example demonstrates how to validate request headers against a defined JSON schema, which requires two specific headers and the header value to conform to specified requirements. + +Create a Route with `request-validation` Plugin as follows: + ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/5 \ --H "X-API-KEY: $admin_key" -X PUT -d ' -{ +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "request-validation-route", "uri": "/get", "plugins": { - "request-validation": { - "body_schema": { - "type": "object", - "required": ["required_payload"], - "properties": { - "required_payload": {"type": "string"}, - "boolean_payload": {"type": "boolean"} - }, - "rejected_msg": "customize reject message" + "request-validation": { + "header_schema": { + "type": "object", + "required": ["User-Agent", "Host"], + "properties": { + "User-Agent": { + "type": "string", + "pattern": "^curl\/" + }, + "Host": { + "type": "string", + "enum": ["httpbin.org", "httpbin"] } + } } + } }, "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:8080": 1 - } + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -}' + }' ``` -The examples below shows how you can configure this Plugin for different validation scenarios: +#### Verify with Request Conforming to the Schema -### Enum validation +Send a request with header `Host: httpbin`, which complies with the schema: + +```shell +curl -i "http://127.0.0.1:9080/get" -H "Host: httpbin" +``` + +You should receive an `HTTP/1.1 200 OK` response similar to the following: ```json { - "body_schema": { - "type": "object", - "required": ["required_payload"], - "properties": { - "enum_payload": { - "type": "string", - "enum": ["enum_string_1", "enum_string_2"], - "default": "enum_string_1" - } - } - } + "args": {}, + "headers": { + "Accept": "*/*", + "Host": "httpbin", + "User-Agent": "curl/7.74.0", + "X-Amzn-Trace-Id": "Root=1-6509ae35-63d1e0fd3934e3f221a95dd8", + "X-Forwarded-Host": "httpbin" + }, + "origin": "127.0.0.1, 183.17.233.107", + "url": "http://httpbin/get" } ``` -### Boolean validation +#### Verify with Request Not Conforming to the Schema -```json -{ - "body_schema": { - "type": "object", - "required": ["bool_payload"], - "properties": { - "bool_payload": { - "type": "boolean", - "default": true +Send a request without any header: + +```shell +curl -i "http://127.0.0.1:9080/get" +``` + +You should receive an `HTTP/1.1 400 Bad Request` response, showing that the request fails to pass validation: + +```text +property "Host" validation failed: matches none of the enum value +``` + +Send a request with the required headers but with non-conformant header value: + +```shell +curl -i "http://127.0.0.1:9080/get" -H "Host: httpbin" -H "User-Agent: cli-mock" +``` + +You should receive an `HTTP/1.1 400 Bad Request` response showing the `User-Agent` header value does not match the expected pattern: + +```text +property "User-Agent" validation failed: failed to match pattern "^curl/" with "cli-mock" +``` + +### Customize Rejection Message and Status Code + +The following example demonstrates how to customize response status and message when the validation fails. + +Configure the Route with `request-validation` as follows: + +```shell +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "request-validation-route", + "uri": "/get", + "plugins": { + "request-validation": { + "header_schema": { + "type": "object", + "required": ["Host"], + "properties": { + "Host": { + "type": "string", + "enum": ["httpbin.org", "httpbin"] } - } + } + }, + "rejected_code": 403, + "rejected_msg": "Request header validation failed." + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -} + }' ``` -### Number or Integer validation +Send a request with a misconfigured `Host` in the header: -```json -{ - "body_schema": { - "type": "object", - "required": ["integer_payload"], - "properties": { - "integer_payload": { +```shell +curl -i "http://127.0.0.1:9080/get" -H "Host: httpbin2" +``` + +You should receive an `HTTP/1.1 403 Forbidden` response with the custom message: + +```text +Request header validation failed. +``` + +### Validate Request Body + +The following example demonstrates how to validate request body against a defined JSON schema. + +The `request-validation` Plugin supports validation of two types of media types: + +* `application/json` +* `application/x-www-form-urlencoded` + +#### Validate JSON Request Body + +Create a Route with `request-validation` Plugin as follows: + +```shell +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "request-validation-route", + "uri": "/post", + "plugins": { + "request-validation": { + "header_schema": { + "type": "object", + "required": ["Content-Type"], + "properties": { + "Content-Type": { + "type": "string", + "pattern": "^application\/json$" + } + } + }, + "body_schema": { + "type": "object", + "required": ["required_payload"], + "properties": { + "required_payload": {"type": "string"}, + "boolean_payload": {"type": "boolean"}, + "array_payload": { + "type": "array", + "minItems": 1, + "items": { "type": "integer", - "minimum": 1, - "maximum": 65535 + "minimum": 200, + "maximum": 599 + }, + "uniqueItems": true, + "default": [200] } + } } + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -} + }' ``` -### String validation +Send a request with JSON body that conforms to the schema to verify: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -H "Content-Type: application/json" \ + -d '{"required_payload":"hello", "array_payload":[301]}' +``` + +You should receive an `HTTP/1.1 200 OK` response similar to the following: ```json { - "body_schema": { - "type": "object", - "required": ["string_payload"], - "properties": { - "string_payload": { - "type": "string", - "minLength": 1, - "maxLength": 32 + "args": {}, + "data": "{\"array_payload\":[301],\"required_payload\":\"hello\"}", + "files": {}, + "form": {}, + "headers": { + ... + }, + "json": { + "array_payload": [ + 301 + ], + "required_payload": "hello" + }, + "origin": "127.0.0.1, 183.17.233.107", + "url": "http://127.0.0.1/post" +} +``` + +If you send a request without specifying `Content-Type: application/json`: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -d '{"required_payload":"hello,world"}' +``` + +You should receive an `HTTP/1.1 400 Bad Request` response similar to the following: + +```text +property "Content-Type" validation failed: failed to match pattern "^application/json$" with "application/x-www-form-urlencoded" +``` + +Similarly, if you send a request without the required JSON field `required_payload`: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -H "Content-Type: application/json" \ + -d '{}' +``` + +You should receive an `HTTP/1.1 400 Bad Request` response: + +```text +property "required_payload" is required +``` + +#### Validate URL-Encoded Form Body + +Create a Route with `request-validation` Plugin as follows: + +```shell +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "request-validation-route", + "uri": "/post", + "plugins": { + "request-validation": { + "header_schema": { + "type": "object", + "required": ["Content-Type"], + "properties": { + "Content-Type": { + "type": "string", + "pattern": "^application\/x-www-form-urlencoded$" + } + } + }, + "body_schema": { + "type": "object", + "required": ["required_payload","enum_payload"], + "properties": { + "required_payload": {"type": "string"}, + "enum_payload": { + "type": "string", + "enum": ["enum_string_1", "enum_string_2"], + "default": "enum_string_1" } + } } + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -} + }' ``` -### Regular expression validation +Send a request with URL-encoded form data to verify: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "required_payload=hello&enum_payload=enum_string_1" +``` + +You should receive an `HTTP/1.1 400 Bad Request` response similar to the following: ```json { - "body_schema": { - "type": "object", - "required": ["regex_payload"], - "properties": { - "regex_payload": { - "type": "string", - "minLength": 1, - "maxLength": 32, - "pattern": "[[^[a-zA-Z0-9_]+$]]" - } - } - } + "args": {}, + "data": "", + "files": {}, + "form": { + "enum_payload": "enum_string_1", + "required_payload": "hello" + }, + "headers": { + ... + }, + "json": null, + "origin": "127.0.0.1, 183.17.233.107", + "url": "http://127.0.0.1/post" } ``` -### Array validation +Send a request without the URL-encoded field `enum_payload`: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "required_payload=hello" +``` + +You should receive an `HTTP/1.1 400 Bad Request` of the following: + +```text +property "enum_payload" is required +``` + +## Appendix: JSON Schema + +The following section provides boilerplate JSON schema for you to adjust, combine, and use with this plugin. For a complete reference, see [JSON schema specification](https://json-schema.org/specification). + +### Enumerated Values ```json { - "body_schema": { - "type": "object", - "required": ["array_payload"], - "properties": { - "array_payload": { - "type": "array", - "minItems": 1, - "items": { - "type": "integer", - "minimum": 200, - "maximum": 599 - }, - "uniqueItems": true, - "default": [200, 302] - } - } + "body_schema": { + "type": "object", + "required": ["enum_payload"], + "properties": { + "enum_payload": { + "type": "string", + "enum": ["enum_string_1", "enum_string_2"], + "default": "enum_string_1" + } } + } } ``` -### Header validation +### Boolean Values ```json { - "header_schema": { - "type": "object", - "required": ["Content-Type"], - "properties": { - "Content-Type": { - "type": "string", - "pattern": "^application\/json$" - } - } + "body_schema": { + "type": "object", + "required": ["bool_payload"], + "properties": { + "bool_payload": { + "type": "boolean", + "default": true + } } + } } ``` -### Combined validation +### Numeric Values ```json { - "body_schema": { - "type": "object", - "required": ["boolean_payload", "array_payload", "regex_payload"], - "properties": { - "boolean_payload": { - "type": "boolean" - }, - "array_payload": { - "type": "array", - "minItems": 1, - "items": { - "type": "integer", - "minimum": 200, - "maximum": 599 - }, - "uniqueItems": true, - "default": [200, 302] - }, - "regex_payload": { - "type": "string", - "minLength": 1, - "maxLength": 32, - "pattern": "[[^[a-zA-Z0-9_]+$]]" - } - } + "body_schema": { + "type": "object", + "required": ["integer_payload"], + "properties": { + "integer_payload": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } } + } } ``` -### Custom rejection message +### Strings ```json { - "uri": "/get", - "plugins": { - "request-validation": { - "body_schema": { - "type": "object", - "required": ["required_payload"], - "properties": { - "required_payload": {"type": "string"}, - "boolean_payload": {"type": "boolean"} - }, - "rejected_msg": "customize reject message" + "body_schema": { + "type": "object", + "required": ["string_payload"], + "properties": { + "string_payload": { + "type": "string", + "minLength": 1, + "maxLength": 32 } } - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:8080": 1 - } } } ``` -## Example usage - -Once you have configured the Plugin, it will only allow requests that are valid based on the configuration to reach the Upstream service. If not, the requests are rejected with a 400 or a custom status code you configured. +### RegEx for Strings -A valid request for the above configuration could look like this: - -```shell -curl --header "Content-Type: application/json" \ - --request POST \ - --data '{"boolean-payload":true,"required_payload":"hello"}' \ - http://127.0.0.1:9080/get +```json +{ + "body_schema": { + "type": "object", + "required": ["regex_payload"], + "properties": { + "regex_payload": { + "type": "string", + "minLength": 1, + "maxLength": 32, + "pattern": "[[^[a-zA-Z0-9_]+$]]" + } + } + } +} ``` -## Delete Plugin +### Arrays -To remove the `request-validation` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect. - -```shell -curl http://127.0.0.1:9180/apisix/admin/routes/5 \ --H "X-API-KEY: $admin_key" -X PUT -d ' +```json { - "uri": "/get", - "plugins": { - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:8080": 1 - } + "body_schema": { + "type": "object", + "required": ["array_payload"], + "properties": { + "array_payload": { + "type": "array", + "minItems": 1, + "items": { + "type": "integer", + "minimum": 200, + "maximum": 599 + }, + "uniqueItems": true, + "default": [200, 302] + } } -}' + } +} ``` diff --git a/docs/zh/latest/plugins/request-validation.md b/docs/zh/latest/plugins/request-validation.md index 5b491a419c61..84bf70e70791 100644 --- a/docs/zh/latest/plugins/request-validation.md +++ b/docs/zh/latest/plugins/request-validation.md @@ -4,7 +4,7 @@ keywords: - APISIX - API 网关 - Request Validation -description: 本文介绍了 Apache APISIX request-validation 插件的相关操作,你可以使用此插件验证将要转发给上游服务的请求。 +description: request-validation 插件会在将请求转发到上游服务之前对其进行验证。此插件使用 JSON Schema 进行验证,并且可以验证请求的标头和正文。 --- + + + + ## 描述 -`request-validation` 插件用于提前验证向上游服务转发的请求。该插件使用 [JSON Schema](https://github.com/api7/jsonschema) 机制进行数据验证,可以验证请求的 `body` 及 `header` 数据。 +`request-validation` 插件会在将请求转发到上游服务之前对其进行验证。此插件使用 [JSON Schema](https://github.com/api7/jsonschema) 进行验证,并且可以验证请求的标头和正文。 + +请参阅 [JSON Schema 规范](https://json-schema.org/specification) 了解有关语法的更多信息。 ## 属性 @@ -39,15 +45,15 @@ description: 本文介绍了 Apache APISIX request-validation 插件的相关操 | rejected_code | integer | 否 | 400 | [200,...,599] | 当请求被拒绝时要返回的状态码。 | | rejected_msg | string | 否 | | | 当请求被拒绝时返回的信息。 | -:::note 注意 +:::note -启用该插件时,至少需要配置 `header_schema` 和 `body_schema` 属性中的任意一个,两者也可以同时使用。 +`header_schema` 和 `body_schema` 属性至少需要配置其一。 ::: -## 启用插件 +## 示例 -以下示例展示了如何在指定路由上启用 `request-validation` 插件,并设置 `body_schema` 字段: +以下示例演示了如何针对不同场景配置 `request-validation`。 :::note @@ -59,238 +65,464 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"/ ::: +### 验证请求标头 + +下面的示例演示如何根据定义的 JSON Schema 验证请求标头,该模式需要两个特定的标头和标头值符合指定的要求。 + +使用 `request-validation` 插件创建路由,如下所示: + ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/5 \ --H "X-API-KEY: $admin_key" -X PUT -d ' -{ +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "request-validation-route", "uri": "/get", "plugins": { - "request-validation": { - "body_schema": { - "type": "object", - "required": ["required_payload"], - "properties": { - "required_payload": {"type": "string"}, - "boolean_payload": {"type": "boolean"} - } + "request-validation": { + "header_schema": { + "type": "object", + "required": ["User-Agent", "Host"], + "properties": { + "User-Agent": { + "type": "string", + "pattern": "^curl\/" + }, + "Host": { + "type": "string", + "enum": ["httpbin.org", "httpbin"] } - "rejected_msg": "customize reject message" + } } + } }, "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:8080": 1 - } + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -}' + }' ``` -以下示例展示了不同验证场景下该插件的 JSON 配置: +#### 使用符合架构的请求进行验证 -### 枚举(Enum)验证 +发送带有标头 `Host: httpbin` 的请求,该请求符合架构: + +```shell +curl -i "http://127.0.0.1:9080/get" -H "Host: httpbin" +``` + +您应该收到类似于以下内容的 `HTTP/1.1 200 OK` 响应: ```json { - "body_schema": { - "type": "object", - "required": ["enum_payload"], - "properties": { - "enum_payload": { - "type": "string", - "enum": ["enum_string_1", "enum_string_2"], - "default": "enum_string_1" - } - } - } + "args": {}, + "headers": { + "Accept": "*/*", + "Host": "httpbin", + "User-Agent": "curl/7.74.0", + "X-Amzn-Trace-Id": "Root=1-6509ae35-63d1e0fd3934e3f221a95dd8", + "X-Forwarded-Host": "httpbin" + }, + "origin": "127.0.0.1, 183.17.233.107", + "url": "http://httpbin/get" } ``` -### 布尔(Boolean)验证 +#### 验证请求是否符合架构 -```json -{ - "body_schema": { - "type": "object", - "required": ["bool_payload"], - "properties": { - "bool_payload": { - "type": "boolean", - "default": true +发送不带任何标头的请求: + +```shell +curl -i "http://127.0.0.1:9080/get" +``` + +您应该收到 `HTTP/1.1 400 Bad Request` 响应,表明请求未能通过验证: + +```text +property "Host" validation failed: matches none of the enum value +``` + +发送具有所需标头但标头值不符合的请求: + +```shell +curl -i "http://127.0.0.1:9080/get" -H "Host: httpbin" -H "User-Agent: cli-mock" +``` + +您应该收到一个 `HTTP/1.1 400 Bad Request` 响应,显示 `User-Agent` 标头值与预期模式不匹配: + +```text +property "User-Agent" validation failed: failed to match pattern "^curl/" with "cli-mock" +``` + +### 自定义拒绝消息和状态代码 + +以下示例演示了如何在验证失败时自定义响应状态和消息。 + +使用 `request-validation` 配置路由,如下所示: + +```shell +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "request-validation-route", + "uri": "/get", + "plugins": { + "request-validation": { + "header_schema": { + "type": "object", + "required": ["Host"], + "properties": { + "Host": { + "type": "string", + "enum": ["httpbin.org", "httpbin"] } - } + } + }, + "rejected_code": 403, + "rejected_msg": "Request header validation failed." + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -} + }' ``` -### 数字范围(Number or Integer)验证 +发送一个在标头中配置错误的 `Host` 的请求: -```json -{ - "body_schema": { - "type": "object", - "required": ["integer_payload"], - "properties": { - "integer_payload": { +```shell +curl -i "http://127.0.0.1:9080/get" -H "Host: httpbin2" +``` + +您应该收到带有自定义消息的 `HTTP/1.1 403 Forbidden` 响应: + +```text +Request header validation failed. +``` + +### 验证请求主体 + +以下示例演示如何根据定义的 JSON Schema 验证请求主体。 + +`request-validation` 插件支持两种媒体类型的验证: + +* `application/json` +* `application/x-www-form-urlencoded` + +#### 验证 JSON 请求主体 + +使用 `request-validation` 插件创建路由,如下所示: + +```shell +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "request-validation-route", + "uri": "/post", + "plugins": { + "request-validation": { + "header_schema": { + "type": "object", + "required": ["Content-Type"], + "properties": { + "Content-Type": { + "type": "string", + "pattern": "^application\/json$" + } + } + }, + "body_schema": { + "type": "object", + "required": ["required_payload"], + "properties": { + "required_payload": {"type": "string"}, + "boolean_payload": {"type": "boolean"}, + "array_payload": { + "type": "array", + "minItems": 1, + "items": { "type": "integer", - "minimum": 1, - "maximum": 65535 + "minimum": 200, + "maximum": 599 + }, + "uniqueItems": true, + "default": [200] } + } } + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -} + }' +``` + +发送符合架构的 JSON Schema 的请求以验证: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -H "Content-Type: application/json" \ + -d '{"required_payload":"hello", "array_payload":[301]}' ``` -### 字符串长度(String)验证 +您应该收到类似于以下内容的 `HTTP/1.1 200 OK` 响应: ```json { - "body_schema": { - "type": "object", - "required": ["string_payload"], - "properties": { - "string_payload": { - "type": "string", - "minLength": 1, - "maxLength": 32 + "args": {}, + "data": "{\"array_payload\":[301],\"required_payload\":\"hello\"}", + "files": {}, + "form": {}, + "headers": { + ... + }, + "json": { + "array_payload": [ + 301 + ], + "required_payload": "hello" + }, + "origin": "127.0.0.1, 183.17.233.107", + "url": "http://127.0.0.1/post" +} +``` + +如果你发送请求时没有指定 `Content-Type:application/json`: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -d '{"required_payload":"hello,world"}' +``` + +您应该收到类似于以下内容的 `HTTP/1.1 400 Bad Request` 响应: + +```text +property "Content-Type" validation failed: failed to match pattern "^application/json$" with "application/x-www-form-urlencoded" +``` + +如果你发送的请求没有必需的 JSON 字段 `required_pa​​yload`: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -H "Content-Type: application/json" \ + -d '{}' +``` + +您应该收到 `HTTP/1.1 400 Bad Request` 响应: + +```text +property "required_payload" is required +``` + +#### 验证 URL 编码的表单主体 + +使用 `request-validation` 插件创建路由,如下所示: + +```shell +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "request-validation-route", + "uri": "/post", + "plugins": { + "request-validation": { + "header_schema": { + "type": "object", + "required": ["Content-Type"], + "properties": { + "Content-Type": { + "type": "string", + "pattern": "^application\/x-www-form-urlencoded$" + } + } + }, + "body_schema": { + "type": "object", + "required": ["required_payload","enum_payload"], + "properties": { + "required_payload": {"type": "string"}, + "enum_payload": { + "type": "string", + "enum": ["enum_string_1", "enum_string_2"], + "default": "enum_string_1" } + } } + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "httpbin.org:80": 1 + } } -} + }' +``` + +发送带有 URL 编码的表单数据的请求来验证: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "required_payload=hello&enum_payload=enum_string_1" ``` -### 正则表达式(Regex)验证 +您应该收到类似于以下内容的 `HTTP/1.1 400 Bad Request` 响应: ```json { - "body_schema": { - "type": "object", - "required": ["regex_payload"], - "properties": { - "regex_payload": { - "type": "string", - "minLength": 1, - "maxLength": 32, - "pattern": "[[^[a-zA-Z0-9_]+$]]" - } - } - } + "args": {}, + "data": "", + "files": {}, + "form": { + "enum_payload": "enum_string_1", + "required_payload": "hello" + }, + "headers": { + ... + }, + "json": null, + "origin": "127.0.0.1, 183.17.233.107", + "url": "http://127.0.0.1/post" } ``` -### 数组(Array)验证 +发送不带 URL 编码字段 `enum_payload` 的请求: + +```shell +curl -i "http://127.0.0.1:9080/post" -X POST \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "required_payload=hello" +``` + +您应该收到以下 `HTTP/1.1 400 Bad Request`: + +```text +property "enum_payload" is required +``` + +## 附录:JSON 模式 + +以下部分提供了样板 JSON 模式,供您调整、组合和使用此插件。有关完整参考,请参阅 [JSON 模式规范](https://json-schema.org/specification)。 + +### 枚举值 ```json { - "body_schema": { - "type": "object", - "required": ["array_payload"], - "properties": { - "array_payload": { - "type": "array", - "minItems": 1, - "items": { - "type": "integer", - "minimum": 200, - "maximum": 599 - }, - "uniqueItems": true, - "default": [200, 302] - } - } + "body_schema": { + "type": "object", + "required": ["enum_payload"], + "properties": { + "enum_payload": { + "type": "string", + "enum": ["enum_string_1", "enum_string_2"], + "default": "enum_string_1" + } } + } } ``` -### 多字段组合(Combined)验证 +### 布尔值 ```json { - "body_schema": { - "type": "object", - "required": ["boolean_payload", "array_payload", "regex_payload"], - "properties": { - "boolean_payload": { - "type": "boolean" - }, - "array_payload": { - "type": "array", - "minItems": 1, - "items": { - "type": "integer", - "minimum": 200, - "maximum": 599 - }, - "uniqueItems": true, - "default": [200, 302] - }, - "regex_payload": { - "type": "string", - "minLength": 1, - "maxLength": 32, - "pattern": "[[^[a-zA-Z0-9_]+$]]" - } - } + "body_schema": { + "type": "object", + "required": ["bool_payload"], + "properties": { + "bool_payload": { + "type": "boolean", + "default": true + } } + } } ``` -### 自定义拒绝信息 +### 数值 ```json { - "uri": "/get", - "plugins": { - "request-validation": { - "body_schema": { - "type": "object", - "required": ["required_payload"], - "properties": { - "required_payload": {"type": "string"}, - "boolean_payload": {"type": "boolean"} - } - }, - "rejected_msg": "customize reject message" - } - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:8080": 1 + "body_schema": { + "type": "object", + "required": ["integer_payload"], + "properties": { + "integer_payload": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } } } } ``` -## 测试插件 +### 字符串 -按上述配置启用插件后,使用 `curl` 命令请求该路由: - -```shell -curl --header "Content-Type: application/json" \ - --request POST \ - --data '{"boolean-payload":true,"required_payload":"hello"}' \ - http://127.0.0.1:9080/get +```json +{ + "body_schema": { + "type": "object", + "required": ["string_payload"], + "properties": { + "string_payload": { + "type": "string", + "minLength": 1, + "maxLength": 32 + } + } + } +} ``` -现在只允许符合已配置规则的有效请求到达上游服务。不符合配置的请求将被拒绝,并返回 `400` 或自定义状态码。 +### 字符串的正则表达式 -## 删除插件 +```json +{ + "body_schema": { + "type": "object", + "required": ["regex_payload"], + "properties": { + "regex_payload": { + "type": "string", + "minLength": 1, + "maxLength": 32, + "pattern": "[[^[a-zA-Z0-9_]+$]]" + } + } + } +} +``` -当你需要删除该插件时,可以通过以下命令删除相应的 JSON 配置,APISIX 将会自动重新加载相关配置,无需重启服务: +### 数组 -```shell -curl http://127.0.0.1:9180/apisix/admin/routes/5 \ --H "X-API-KEY: $admin_key" -X PUT -d ' +```json { - "uri": "/get", - "plugins": { - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:8080": 1 - } + "body_schema": { + "type": "object", + "required": ["array_payload"], + "properties": { + "array_payload": { + "type": "array", + "minItems": 1, + "items": { + "type": "integer", + "minimum": 200, + "maximum": 599 + }, + "uniqueItems": true, + "default": [200, 302] + } } -}' + } +} ```