mikyll commented on issue #11815:
URL: https://github.com/apache/apisix/issues/11815#issuecomment-2525307388
Hi 🙂
To be more easily addressed, your question could be improved with
**debugging details**, such as:
- APISIX logs (Nginx access/error);
- what you expected/what you got instead;
- how do you load plugins;
- how do you enable them (e.g. route declaration);
---
Here's an example on how you could achieve what you want:
**Task**: retrieve the request ID from a header and return it in response
body.
**Possible Solution**: custom plugin.
## Example
Custom plugin, file `plugins/page-403.lua`:
```lua
local core = require("apisix.core")
local plugin_name = "page-403"
local schema = {
type = "object",
properties = {},
}
local _M = {
version = 0.1,
priority = 0, -- This must be lower than request-id priority (12015)
name = plugin_name,
schema = schema,
}
function _M.rewrite(conf, ctx)
-- Obtain the header from the request and retrieve the UUID
local uuid = core.request.header(ctx, "x-coraza-uuid")
if uuid then
-- Include the UUID in body's response
core.response.exit(403, [[
<html>
<body>
<h1>403 Forbidden</h1>
<p>Your UUID: ]] .. uuid .. [[</p>
</body>
</html>
]])
else
core.log.warn("Request ID not found!")
end
end
return _M
```
Plugin `page-403` will not forward the request to the upstream, if it finds
a header "x-coraza-uuid", and directly respond with `403 Forbidden` and the
request ID in the body. If it doesn't find the header, it'll let APISIX forward
the request to the upstream, and log a warning message.
APISIX configuration, file `conf/config.yaml` (see
[config.yaml.example](https://github.com/apache/apisix/blob/d599d20c25cc3ca275da27d1174398d9e1d91fd5/conf/config.yaml.example#L438-L537)):
```yaml
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
plugins: # plugin list (sorted by priority)
- real-ip # priority: 23000
- client-control # priority: 22000
- proxy-control # priority: 21990
- request-id # priority: 12015
- zipkin # priority: 12011
#- skywalking # priority: 12010
#- opentelemetry # priority: 12009
- ext-plugin-pre-req # priority: 12000
- fault-injection # priority: 11000
- mocking # priority: 10900
- serverless-pre-function # priority: 10000
#- batch-requests # priority: 4010
- cors # priority: 4000
- ip-restriction # priority: 3000
- ua-restriction # priority: 2999
- referer-restriction # priority: 2990
- csrf # priority: 2980
- uri-blocker # priority: 2900
- request-validation # priority: 2800
- chaitin-waf # priority: 2700
- multi-auth # priority: 2600
- openid-connect # priority: 2599
- cas-auth # priority: 2597
- authz-casbin # priority: 2560
- authz-casdoor # priority: 2559
- wolf-rbac # priority: 2555
- ldap-auth # priority: 2540
- hmac-auth # priority: 2530
- basic-auth # priority: 2520
- jwt-auth # priority: 2510
- jwe-decrypt # priority: 2509
- key-auth # priority: 2500
- consumer-restriction # priority: 2400
- attach-consumer-label # priority: 2399
- forward-auth # priority: 2002
- opa # priority: 2001
- authz-keycloak # priority: 2000
#- error-log-logger # priority: 1091
- proxy-cache # priority: 1085
- body-transformer # priority: 1080
- proxy-mirror # priority: 1010
- proxy-rewrite # priority: 1008
- workflow # priority: 1006
- api-breaker # priority: 1005
- limit-conn # priority: 1003
- limit-count # priority: 1002
- limit-req # priority: 1001
#- node-status # priority: 1000
- ai-proxy # priority: 999
#- brotli # priority: 996
- gzip # priority: 995
- server-info # priority: 990
- traffic-split # priority: 966
- redirect # priority: 900
- response-rewrite # priority: 899
- degraphql # priority: 509
- kafka-proxy # priority: 508
#- dubbo-proxy # priority: 507
- grpc-transcode # priority: 506
- grpc-web # priority: 505
- http-dubbo # priority: 504
- public-api # priority: 501
- prometheus # priority: 500
- datadog # priority: 495
- loki-logger # priority: 414
- elasticsearch-logger # priority: 413
- echo # priority: 412
- loggly # priority: 411
- http-logger # priority: 410
- splunk-hec-logging # priority: 409
- skywalking-logger # priority: 408
- google-cloud-logging # priority: 407
- sls-logger # priority: 406
- tcp-logger # priority: 405
- kafka-logger # priority: 403
- rocketmq-logger # priority: 402
- syslog # priority: 401
- udp-logger # priority: 400
- file-logger # priority: 399
- clickhouse-logger # priority: 398
- tencent-cloud-cls # priority: 397
- inspect # priority: 200
#- log-rotate # priority: 100
# <- recommend to use priority (0, 100) for your custom plugins
- example-plugin # priority: 0
#- gm # priority: -43
#- ocsp-stapling # priority: -44
- aws-lambda # priority: -1899
- azure-functions # priority: -1900
- openwhisk # priority: -1901
- openfunction # priority: -1902
- serverless-post-function # priority: -2000
- ext-plugin-post-req # priority: -3000
- ext-plugin-post-resp # priority: -4000
# Our custom plugin
- page-403
```
Route declaration, file `conf/apisix.yaml`:
```yaml
routes:
- id: request-uuid
uri: /api/test
upstream:
nodes:
"httpbin.org": 1
type: roundrobin
plugins:
# this will redirect each request from /api/test to httpbin.org/get
proxy-rewrite:
uri: /get
method: GET
# this will add a unique ID to each request, and store it in header
"x-coraza-uuid"
request-id:
header_name: x-coraza-uuid
page-403:
- id: request-uuid-not-found
uri: /api/test2
upstream:
nodes:
"httpbin.org": 1
type: roundrobin
plugins:
# this will redirect each request from /api/test to httpbin.org/get
proxy-rewrite:
uri: /get
method: GET
page-403:
#END
```
Example testing with Docker:
```bash
docker run --name apache-apisix --rm \
-p 9080:9080 \
-e APISIX_STAND_ALONE=true \
-v "$(pwd)/conf/config.yaml:/usr/local/apisix/conf/config.yaml" \
-v "$(pwd)/conf/apisix.yaml:/usr/local/apisix/conf/apisix.yaml" \
-v
"$(pwd)/plugins/page-403.lua:/usr/local/apisix/apisix/plugins/page-403.lua" \
apache/apisix
```
Try sending a request to `/api/test` (request id in header):
```bash
curl -i localhost:9080/api/test
HTTP/1.1 403 Forbidden
Date: Sat, 07 Dec 2024 20:33:02 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/3.11.0
x-coraza-uuid: a5f51a39-ad95-45b6-881c-41694019abf0
<html>
<body>
<h1>403 Forbidden</h1>
<p>Your UUID: a5f51a39-ad95-45b6-881c-41694019abf0</p>
</body>
</html>
```
Try sending a request to `/api/test` (request id in header):
```bash
curl -i localhost:9080/api/test2
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 298
Connection: keep-alive
Date: Sat, 07 Dec 2024 20:41:18 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.11.0
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "localhost",
"User-Agent": "curl/8.5.0",
"X-Amzn-Trace-Id": "Root=1-6754b2ee-0e88a1a4491a10395c58e8ee",
"X-Forwarded-Host": "localhost"
},
"origin": "172.17.0.1, 31.XXX.XXX.XXX",
"url": "http://localhost/get"
}
```
To watch logs:
```bash
docker logs -f apache-apisix
2024/12/07 20:44:32 [warn] 166#166: *182451 [lua] page-403.lua:33:
phase_func(): Request ID not found!, client: 172.17.0.1, server: _, request:
"GET /api/test2 HTTP/1.1", host: "localhost:9080"
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]