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]

Reply via email to