如何修复Rails Devise表单CSRF真实性令牌不匹配问题

问题说明
表单input字段内的authenticity token与head元素中声明的对应值不匹配,提交Devise注册表单返回422 Unprocessable Entity错误,无法正常创建Devise User。
触发前置操作:删除master.key文件后,重新执行rails credentials:edit命令生成了新的RAILS_MASTER_KEY和SECRET_KEY_BASE。
修复步骤
按顺序执行以下操作即可解决:
- 完全重启Rails服务
密钥相关配置修改后不会被热重载加载,必须终止当前运行的rails server进程,重新启动服务,确保新的SECRET_KEY_BASE被应用加载。 - 清除浏览器站点数据
旧的CSRF token、session cookie是基于原SECRET_KEY_BASE加密生成的,和新密钥不兼容。清除对应站点的Cookie、本地存储、缓存数据,或直接使用浏览器无痕模式打开注册页测试。 - 校验密钥加载正确性
打开Rails控制台执行以下命令,确认当前环境加载的密钥是新生成的值:Rails.application.credentials.secret_key_base- 如果返回值为空,检查当前目录下的
master.key和config/credentials.yml.enc是否匹配,不要混用旧的credentials文件和新的master.key - 如果返回值是旧的密钥,检查环境变量中是否硬编码了旧的
SECRET_KEY_BASE,替换为新生成的值即可
- 如果返回值为空,检查当前目录下的
- 核对布局文件CSRF配置
检查app/views/layouts/application.html.erb的head区域,确保存在以下两行标签,不要手动修改或删除:
Devise表单使用默认的<%= csrf_meta_tags %> <%= csp_meta_tag %>form_with生成即可,不要手动添加、覆盖authenticity token隐藏字段。 - 问题定位验证(仅测试使用,禁止上线)
如果以上操作后仍报错,可以在注册相关控制器中临时添加以下配置,确认是否为CSRF校验导致的问题:
添加后如果表单可以正常提交,说明问题仍然出在密钥加载、缓存环节,回到前3步逐一核对即可,验证完成后必须删除该行配置。skip_forgery_protection
注意:执行credentials相关命令时注意拼写,正确命令为
rails credentials:edit,拼写错误会导致配置不生效。
内容的提问来源于stack exchange,提问作者InterstellarBrandon
相关产品推荐
相关产品推荐

