自定义openstreetmap-website时Rails Authenticity Token报错与随机登出问题求助
问题根因说明
你遇到的ActionController::InvalidAuthenticityToken报错和随机强制登出确实是强关联问题,核心原因都是用户会话session丢失或不匹配:Rails的CSRF令牌默认存储在用户session中,session失效/丢失时令牌校验失败就会抛InvalidAuthenticityToken错误,同时session丢失也会直接触发用户登出。你之前单独禁用单控制器的令牌校验,只是屏蔽了报错,并没有解决session丢失的根问题,所以登出问题反而更严重。
排查优先级&解决方案
1. 优先排查反向代理和会话配置(90%概率可以解决问题)
你站点用HTTPS部署,大概率是反向代理配置不当导致Rails没有正确识别HTTPS请求,进而导致会话cookie写入异常:
- 首先检查Nginx反向代理配置,确保请求转发时携带了正确的源站信息,需要在站点配置的location块中添加以下配置:
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $remote_addr;
- 然后修改Rails生产环境配置,路径为
config/environments/production.rb,添加配置让Rails信任反向代理的请求头:
config.action_dispatch.trusted_proxies = ["127.0.0.1", "::1"]
- 最后核对会话存储配置,路径为
config/initializers/session_store.rb,确认以下参数配置正确:- domain参数和你实际站点域名匹配,如果不需要子域名共享会话可以直接设为
:autodetect - 全站HTTPS的情况下需要将
secure:参数设为true,确保浏览器只在HTTPS请求中携带会话cookie same_site:参数设为:lax即可,符合当前浏览器的cookie安全规则
- domain参数和你实际站点域名匹配,如果不需要子域名共享会话可以直接设为
2. 全站禁用CSRF令牌校验的正确方法
不需要给每个控制器单独加配置,直接修改根控制器app/controllers/application_controller.rb,添加一行代码即可全局生效:
skip_before_action :verify_authenticity_token
修改完成后重启Rails服务,全站的CSRF校验就会关闭。注意该操作必须在完成上述session配置修复后再做,否则依然会存在随机登出问题。
3. 遗留问题排查
如果完成上述配置后还是存在随机登出问题,可以直接查看Rails生产日志(默认路径为log/production.log),找到用户登出时对应的请求记录,核对请求携带的session_id是否和之前的会话一致:
- 如果session_id发生变化,说明浏览器没有正确携带会话cookie,继续排查cookie的domain、secure、same_site属性配置即可
- 如果session_id没有变化,排查是否有代码逻辑异常清空了会话,或者数据库中对应用户的会话记录被误删
内容的提问来源于stack exchange,提问作者Luciano Jones
相关产品推荐
相关产品推荐

