Redirect HTTP post url to HTTPS on Nginx

Asked

Viewed 1,376 times

3

I have an application that I receive POSTS of return of the payment system, but currently we force the use of SSL for our site, I made the HTTP redirection to HTTPS, but I get error 404 when the POSTBACK system sends the POST to the URL http://.... , when my server tries to redirect to HTTPS( Or does not try ) error 404 appears.

NGNIX file:

# FORGE CONFIG (DOT NOT REMOVE!)
include forge-conf/magicaonline.com.br/before/*;

server {
    listen 80;
    listen [::]:80;
    return 307 https://magicaonline.com.br/$1;
}

server {
    listen 443 http2;
    listen [::]:443 http2;
    server_name .magicaonline.com.br;
    root /home/forge/magicaonline.com.br/public;

    if ($host = 'www.magicaonline.com.br') {
        rewrite ^/(.*)$ https://magicaonline.com.br/$1 permanent;
    }

    #if ($scheme = http) {
    #    return 302 https://$server_name$request_uri;
    #}

    # FORGE SSL (DO NOT REMOVE!)
    ssl_certificate /etc/nginx/ssl/magicaonline.com.br/132754/server.crt;
    ssl_certificate_key /etc/nginx/ssl/magicaonline.com.br/132754/server.key;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'xxxxx';
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/dhparams.pem;

    index index.html index.htm index.php;

    charset utf-8;

    # FORGE CONFIG (DOT NOT REMOVE!)
    include forge-conf/magicaonline.com.br/server/*;

    location /lp/ {
        try_files $uri $uri/ @wordpress;
    }

    location @wordpress {
        rewrite /lp/ /lp/index.php;
    }

    location ^/lp/index.php(/.*)?$ {
        fastcgi_split_path_info ^(/lp/index.php)(/.*)$;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
        include fastcgi_params;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/magicaonline.com.br-error.log error;

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

# FORGE CONFIG (DOT NOT REMOVE!)
include forge-conf/magicaonline.com.br/after/*;

There are possibilities to make it happen ?

I need this solution because the payment system does not accept to modify the URL of POSTBACK.

2 answers

1

302 turns your POST into a GET, the browser itself performs this behavior.

Following Joao’s recommendation, which is correct, we have a simple case:

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" - "$request_body" - $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';

    server {
        listen       8181;
        server_name  localhost;

        access_log /my_path/log/nginx.log;

        location / {
            proxy_pass_header on;
            proxy_pass http://localhost:8080/receive;
        }
    }

    include servers/*;
}

Here we have a server listening to port 8181, with log writing enabled. By performing a simple post using Curl on this route:

curl -X POST -H 'Content-Type: application/json' -d '{"product": "New product", "id": "1"}' http://localhost:81

The request will be redirected to port 8080, keeping the headers. To test we can create a server nodejs listening to this port:

var express = require('express')
var fs = require('fs')
var url = require('url')
var app = express()

app.post('/receive', function(request, respond) {
    var body = ''

    filePath = __dirname + '/post.txt'
    request.on('data', function(data) {
        body += data
    })

    request.on('end', function (){
        body = body + '\n'
        fs.appendFile(filePath, body, function() {
            respond.end()
        })
    })
})

app.listen(8080)   

To run the Node server just use the commands:

npm init
npm install --save express
node index.js

This server receives the Nginx redirect and writes the post in a file called post.txt.

When performing the whole process we will have as input in this file:

{"product": "New product", "id": "1"}

0

In fact, according to HTTP spec, the user-agent 302 should not redirect the entire request. I believe that what happens is that your request, when it reaches 302, becomes a GET, and this causes your 404 (since probably the server is just waiting for a POST).

I think the ideal thing would be for you to use a Nginx proxy named Proxy Pass.

Update your redirect to:

if ($scheme = http) {
  proxy_pass_header on;
  proxy_pass https://$server_name$request_uri;
}

can solve your problem. The first line activates the sending of headers, which will be required for your Postback and is disabled by default, and the second sets the pro proxy url.

  • John, first thank you for your attention.

  • Unfortunately unable to make it work, can give me an example inside the file that is above ?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.