如果这个第三方恰好在POST中发送了一些数据,并且您需要使用相同的数据在参数中创建GET,经过数天的头痛之后,我找到的唯一解决方案是使用nginx的nfs模块。
我正在使用带有nginx和certbot的docker镜像,但它缺少nfs,所以我不得不进行扩展:
docker-compose
version: '3.9'
services:
reverse:
restart: unless-stopped
build:
context: .
dockerfile: dockerfile
image: <image_name>
container_name: reverse
env_file:
- ./nginx-certbot.env
ports:
- 80:80
- 443:443
volumes:
- ./ssl_conf:/etc/letsencrypt
- ./nginx/user_conf.d:/etc/nginx/user_conf.d
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/includes:/etc/nginx/includes/
- ./logs:/var/log/nginx:rw
- ./nginx/njs:/etc/nginx/njs/
Dockerfile(用于扩展njs包)
FROM jonasal/nginx-certbot:3.3.1-nginx1.23.3-alpine
RUN apk add nginx-module-njs
在nginx配置文件中,您需要添加以下内容:
load_module modules/ngx_http_js_module.so;
load_module modules/ngx_stream_js_module.so;
http {
...
js_path /etc/nginx/njs/;
js_import main.js;
...
}
现在,您已经准备使用njs来操作数据了。
创建一个main.js文件,将POST有效负载存储到文件中以便于读取。
var fs = require('fs');
var STORAGE = "/tmp/njs_storage"
function save(r) {
fs.writeFileSync(STORAGE, r.requestBody);
r.internalRedirect("/readdirect")
}
function readdirect(r) {
var data = "";
try {
data = fs.readFileSync(STORAGE);
} catch (e) {
}
r.internalRedirect("/access?" + data)
}
export default {save, readdirect}
还有nginx file.conf文件
location / {
include /etc/nginx/includes/common_location.conf;
resolver 127.0.0.11 ipv6=off;
set $upstream localhost:4200;
proxy_pass http://$upstream;
}
location /apple {
js_content main.save;
}
location /readdirect {
js_content main.readdirect;
}
location = /access {
include /etc/nginx/includes/common_location.conf;
proxy_method GET;
resolver 127.0.0.11 ipv6=off;
rewrite ^ https://example.com/access/ break;
}
现在基本上,带有正文有效负载的POST转换为GET参数?code=1&state=2,以在前端中使用(并模仿其他社交登录的行为)。
找到正确的解决方案并不容易(尝试使用LUA扩展,但版本不匹配等),但这一切都是值得的。