简体   繁体   中英

ActionController::InvalidAuthenticityToken at login using NGINX and Rails

I implemented a reverse proxy to access my rails application. However, whenever I try logging in, I am met with a ActionController::InvalidAuthenticityToken error every time whether admin or non-admin accoount. I read that you need to include proxy_set_header X-Forwarded-Proto https; for it to work but thus far have not for me.

This is my current nginx conf file

upstream backend{
        server localhost:3000;
    }
    server {
        listen       80;
        listen  443 ssl;
        server_name  localhost;
        ssl_certificate localhost.cert;
        ssl_certificate_key localhost.key;

        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://backend;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-Ssl on;
        }

When I login using localhost:3000,which is the hostname for my rails app, it logs in. So the problem lies with nginx. Also here are my error logs from Rails.

在此处输入图像描述

在此处输入图像描述

Any advice on how to solve?

EDIT: Updated nginx conf file

upstream backend{
        server localhost:3000;
    }
    server {
        listen       80;
        listen  443 ssl;
        server_name  localhost;
        ssl_certificate localhost.cert;
        ssl_certificate_key localhost.key;

        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://backend;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-Ssl on;
            proxy_set_header origin 'http://localhost:3000';
            proxy_set_header X-Forwarded-Port 443;
        }

Above solution did not work for me but pushed me to investigate proxy variables.

I could make it work with the following snippet:

server {
  listen 443;
  location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Origin https://$http_host;
    proxy_redirect off;
    proxy_pass http://web:3000;
  }
  ...
}

What was important was: - using $http_host instead of $host . In case of non default port number, $http_host also contains the port number. - Setting port number using $http_host in X-Forwarded-Host header in addition to Host - Setting Origin

In particular, setting origin with an incorrect header allowed me to have errors like this in rails and debug it more easily:

web_1 | W, [2020-05-04T13:30:33.381473 #1] WARN --: [cc52d343-5826-4900-b0d8-477714cf9dc4] HTTP Origin header (https://localhost:443) didn't match request.base_url (https://localhost)

Try to fix by adding more headers X-Forwarded-Ssl on , X-Forwarded-Port 443 , X-Forwarded-Host "your hostname" , X-Forwarded-Proto https .

CSRF tokens are checked by ActionController ( compares the request.base_url with the origin header )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM