csw*_*abe 2 ruby-on-rails nginx csrf ruby-on-rails-6
我实现了一个反向代理来访问我的 Rails 应用程序。但是,每当我尝试登录时,ActionController::InvalidAuthenticityToken无论是管理员帐户还是非管理员帐户,我每次都会遇到错误。我读到你需要包含proxy_set_header X-Forwarded-Proto https;它才能工作,但到目前为止对我来说还没有。
这是我当前的 nginx conf 文件
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;
}
Run Code Online (Sandbox Code Playgroud)
当我使用 localhost:3000(这是我的 Rails 应用程序的主机名)登录时,它会登录。所以问题出在 nginx 上。这里还有我来自 Rails 的错误日志。
有什么建议如何解决吗?
编辑:更新了 nginx conf 文件
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;
}
Run Code Online (Sandbox Code Playgroud)
上述解决方案对我不起作用,但促使我调查代理变量。
我可以使用以下代码片段使其工作:
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;
}
...
}
Run Code Online (Sandbox Code Playgroud)
重要的是: - 使用$http_host而不是$host. 如果非默认端口号,$http_host还包含端口号。-除了
- 设置之外,在标头$http_host中使用设置端口号X-Forwarded-HostHostOrigin
特别是,使用不正确的标头设置 origin 可以让我在 Rails 中出现这样的错误,并且可以更轻松地调试它:
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)