RoR 5.1与Elm集成:使用csrf-xhr解决CSRF令牌验证失败问题
解决Rails 5.1 + Elm 结合csrf-xhr的CSRF验证问题
我明白你现在的困扰——手动复制JS文件到assets目录确实不够优雅,而且JS生态的编译问题也容易让人头大。下面给你一套更规范的解决方案,不用再手动复制文件,还能避免编译错误:
第一步:用npm/yarn管理依赖(推荐)
首先放弃手动复制文件的方式,用包管理器来安装csrf-xhr,这样能自动管理版本和依赖:
- 如果你用yarn(Rails 5.1+默认支持),在项目根目录运行:
yarn add csrf-xhr - 或者用npm:
npm install csrf-xhr --save
第二步:根据你的Rails资产管道选择引入方式
Rails 5.1有两种常见的资产管理方式,对应不同的引入方法:
方式一:使用Webpacker(推荐,更符合现代JS生态)
如果你的项目启用了Webpacker(可以看根目录有没有app/javascript/packs文件夹):
- 打开
app/javascript/packs/application.js,添加一行导入:import 'csrf-xhr' - 确保Webpacker正常编译:
- 开发环境下,启动服务器时同时运行
rails webpacker:watch(或者直接用rails s,新版Webpacker会自动监听) - 生产环境运行
rails webpacker:compile
- 开发环境下,启动服务器时同时运行
- 在你的布局文件(比如
app/views/layouts/application.html.erb)里,替换原来的javascript_include_tag为Webpacker的标签:<%= javascript_pack_tag 'application' %>
方式二:使用传统Sprockets资产管道
如果你的项目还是用旧的Sprockets(app/assets/javascripts为主):
- 先让Sprockets能读取node_modules里的文件,打开
config/initializers/assets.rb,添加:Rails.application.config.assets.paths << Rails.root.join('node_modules') - 打开
app/assets/javascripts/application.js,用Sprockets的require语法引入:
(注意路径://= require csrf-xhr/dist/csrf-xhrcsrf-xhr包的编译好的文件在dist目录下,所以要写全路径) - 重启你的Rails服务器,让Sprockets加载新的路径配置。
第三步:确保CSRF元标签存在
不管用哪种方式,都要确保你的布局文件里有Rails默认的CSRF元标签,csrf-xhr会自动读取这个标签里的令牌:
<%= csrf_meta_tags %>
这个标签默认应该在布局的<head>里,如果没有的话加上就行。
常见编译错误排查
- Webpacker编译失败:如果是Webpacker相关错误,先检查有没有安装Webpacker,运行
rails webpacker:install初始化(Rails 5.1可能需要手动执行这一步),然后再重新安装依赖。 - Sprockets找不到文件:检查
node_modules/csrf-xhr/dist/csrf-xhr.js是否存在,如果路径不对,调整require里的路径;另外确认assets.rb里的路径配置已经生效,重启服务器试试。 - 请求还是报CSRF错误:打开浏览器开发者工具的Network标签,查看发送的请求头里有没有
X-CSRF-Token字段,如果没有,说明csrf-xhr没有正确加载,检查引入步骤有没有遗漏。
这样用包管理器管理依赖,不仅比手动复制文件更规范,后续更新csrf-xhr也只需要运行yarn upgrade csrf-xhr或者npm update csrf-xhr就行,不用再手动替换文件啦。
内容的提问来源于stack exchange,提问作者ngw
相关产品推荐
相关产品推荐

