You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails(Heroku+Cloudflare)自定义域名注册报错原因及解决求助

Rails + Heroku + Cloudflare下ActionController::InvalidAuthenticityToken错误的原因与解决办法

问题原因

Cloudflare作为SSL终止服务,会把用户发起的HTTPS请求转换成HTTP转发给Heroku。这导致Rails生成的request.base_url是HTTP协议,但浏览器发送的Origin请求头是HTTPS(因为用户访问的是HTTPS域名)。Rails的CSRF验证机制会对比这两个值的协议、域名等信息,协议不匹配就会触发ActionController::InvalidAuthenticityToken错误,返回422状态码。而Heroku原生域名提交正常,是因为原生域名的请求没有经过Cloudflare的协议转换,协议始终一致。

解决办法

1. 让Rails信任Cloudflare转发头,识别真实请求协议

在config/environments/production.rb中添加以下配置:

# 信任Cloudflare官方源IP段,确保转发头可信
config.action_dispatch.trusted_proxies = %w[173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22]
# 开启强制SSL,此时Rails能识别真实的HTTPS请求
config.force_ssl = true

这段配置告诉Rails,来自Cloudflare IP的请求里的X-Forwarded-Proto头是可信的,Rails会用该头的协议生成request.base_url,使其与Origin头的HTTPS协议保持一致。

2. 调整Cloudflare的SSL模式设置

登录Cloudflare后台,进入目标域名的SSL/TLS设置页面:

  • 将SSL模式设置为完全(Full)或严格(Full strict),禁用「灵活(Flexible)」模式。灵活模式下Cloudflare到Heroku的请求是HTTP,容易引发协议不匹配问题;完全模式下Cloudflare与Heroku之间也采用HTTPS通信,既安全又能避免头信息冲突。

3. 验证请求头与base_url的一致性

可以临时在控制器中添加调试接口,确认相关参数是否正常:

def check_request_info
  render plain: <<~TEXT
    X-Forwarded-Proto: #{request.headers['X-Forwarded-Proto']}
    Origin: #{request.headers['Origin']}
    request.base_url: #{request.base_url}
  TEXT
end

部署后访问该接口,确认三个值的协议均为https,即可保证CSRF验证正常通过。

内容的提问来源于stack exchange,提问作者wired for freedom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 23:33:25