Errbit容器经Nginx HTTPS反向代理后无法登录问题求助
问题:HTTPS访问Errbit无法登录,HTTP正常(Devise认证场景)
环境说明
- Errbit容器以HTTP协议运行,Nginx作为反向代理接收HTTPS请求并转发至Errbit的HTTP服务
- Errbit采用Devise实现用户认证,仅HTTPS访问时登录失败,HTTP访问正常
Nginx配置
server { listen 80 default_server; server_name _; access_log /var/log/nginx/errbit.access.log main; error_log /var/log/nginx/errbit.error.log warn; location / { proxy_pass http://errbit:8080; proxy_set_header Host $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-Proto $scheme; } location ~ /.well-known/acme-challenge/ { root /var/www/certbot; } } server { listen 443 ssl; http2 on; ssl_certificate /etc/letsencrypt/live/mydomain.de/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mydomain.de/privkey.pem; server_name mydomain.de; root /var/www/html; index index.html; access_log /var/log/nginx/errbit.access.log main; error_log /var/log/nginx/errbit.error.log warn; location ~/.well-known/acme-challenge/ { root /var/www/certbot; } location / { proxy_pass http://errbit:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header X-XSRF-TOKEN $http_x_xsrf_token; } }
Errbit配置
- 使用仓库默认Puma配置
- 未设置
ERRBIT_ENFORCE_SSL,预期由Nginx处理SSL,Errbit无需感知SSL配置
现象与日志分析
现象
- HTTPS和HTTP均能正常显示登录页
- HTTP访问可成功登录;HTTPS登录时弹出提示
You need to sign in or sign up before continuing.(对应401 Unauthorized),并跳转回登录页
关键日志片段
Started POST "/users/sign_in" for 87.145.10.148 at 2024-08-07 10:30:36 +0000 Processing by Devise::SessionsController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"vy9n792gHd0eeEKOo2sPVZUomk0U+bDWU6ahszuLS7P3XVfA7V6/bjNpN6EbJ0svEdqQF+ltWUp9vHyBk1ysLw==", "user"=>{"email"=>"marion.dickten@dcs-fuerth.de", "password"=>"[FILTERED]", "remember_me"=>"0"}} Can't verify CSRF token authenticity. # ... 省略数据库操作日志 ... Redirected to http://mydomain.de/ Completed 302 Found in 156ms Started GET "/" for 87.145.10.148 at 2024-08-07 10:30:36 +0000 Processing by AppsController#index as HTML Completed 401 Unauthorized in 1ms
问题点提炼
- CSRF令牌验证失败:HTTPS请求下Devise无法验证CSRF令牌
- 重定向协议不匹配:登录成功后被重定向到HTTP站点,而非HTTPS
- 会话失效:访问根路径时返回401,说明会话Cookie未被正确携带
原因分析
- 协议感知缺失:HTTPS的Nginx配置未传递
X-Forwarded-Proto头,导致Rails(Errbit基于Rails)认为所有请求都是HTTP,生成的CSRF令牌、会话Cookie和重定向URL均基于HTTP协议 - Cookie属性错误:由于Rails认为请求是HTTP,生成的会话Cookie没有
Secure属性,HTTPS环境下浏览器会拒绝携带该Cookie,导致认证失效 - CSRF令牌不匹配:HTTP环境下生成的CSRF令牌在HTTPS请求中提交,因协议上下文不一致导致验证失败
解决方案
1. 修改Nginx HTTPS配置,补充协议头
更新HTTPS server块的location /配置,添加X-Forwarded-Proto头,并移除无效的X-XSRF-TOKEN手动设置:
location / { proxy_pass http://errbit:8080; proxy_set_header Host $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-Proto $scheme; # 新增:告诉Rails原始请求协议 proxy_http_version 1.1; # 移除proxy_set_header X-XSRF-TOKEN $http_x_xsrf_token; 该设置无效 }
2. 配置Errbit信任反向代理
Rails需要明确信任Nginx所在的IP网段,才能正确识别X-Forwarded-*头。如果使用Docker部署,添加环境变量:
-e RAILS_TRUSTED_PROXIES=172.18.0.0/16
(注:172.18.0.0/16为示例网段,需根据实际Docker子网调整,可从日志中的172.18.0.4推断)
3. 验证与收尾
- 重启Nginx和Errbit容器
- 用HTTPS访问登录,检查日志中无CSRF验证失败提示,重定向目标为
https://mydomain.de/,且能正常访问根路径 - 确认正常后,可修改HTTP server块,将所有请求重定向到HTTPS:
server { listen 80 default_server; server_name _; return 301 https://$host$request_uri; location ~ /.well-known/acme-challenge/ { root /var/www/certbot; } }
内容的提问来源于stack exchange,提问作者MDickten
相关产品推荐
相关产品推荐

