If this 3rd-party happened to send you some data along in the POST and you needed it to create a GET with that same data in the arguments, after days banging my head the only solution I found was using nginx's nfs module.
I am using a docker image with nginx and certbot, but it lacked nfs so I had to extend it:
docker-compose
version: '3.9'
services:
reverse:
restart: unless-stopped
#image: jonasal/nginx-certbot:3.3.1-nginx1.23.3
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 (to extend the njs package)
FROM jonasal/nginx-certbot:3.3.1-nginx1.23.3-alpine
RUN apk add nginx-module-njs
In nginx conf you have to add
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;
...
}
And now you're ready to use njs to manipulate data.
Create a main.js that will store the POST payload in a file to then read it
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}
And the 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;
}
So now basically the POST with body payload transforms into a GET with args ?code=1&state=2 to use in your frontend (and mimic the behaviour of other social logins).
Wasn't easy to find the right solution (tried to extend with LUA, but versions mismatch, etc.) but it was worth the hassle