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

React+Rails前后端POST请求触发ActionController::InvalidAuthenticityToken错误如何解决

问题根因

从Rails日志可以直接定位错误触发原因:

  • 你的前端服务运行在http://localhost:3000,Rails后端运行在http://localhost:3006,属于跨域请求
  • Rails默认开启CSRF(跨站请求伪造)保护,非GET类请求会校验Origin头或者请求携带的CSRF令牌,前后端分离架构下默认不会携带CSRF令牌,同时Origin不匹配就会抛出ActionController::InvalidAuthenticityToken错误
解决方案

方案1:纯API服务场景直接跳过CSRF校验

如果你的Rails应用仅作为前后端分离架构的API服务,不需要处理传统浏览器表单提交,可以直接关闭对应接口的CSRF校验:
在PlayersController中添加跳过校验的逻辑即可:

class PlayersController < ApplicationController
  # 新增这一行,跳过当前控制器所有接口的CSRF校验
  skip_before_action :verify_authenticity_token

  def update_or_create
    # 原有逻辑不变
    puts ("Update or Create hit")
    @player = Player.create_or_find_by(name: player_params[:name])
    puts (player_params)
    @player.update(class: player_params[:class], lvl: player_params[:level], atk: player_params[:atk], sAtk: player_params[:sAtk], def: player_params[:def], sDef: player_params[:sDef], spd: player_params[:spd], hp: player_params[:hp])
    # 注意你原有代码的render写法有语法错误,应该是render json: @player而非json{@player}
    render json: @player
  end

  private
  def player_params
    params.require(:player).permit(:name, :inv_hash, :lvl, :name, :class, :atk, :def, :sAtk, :sDef, :spd, :hp, :move_distance)
  end
end

如果整个应用都是API服务,可以直接把skip_before_action :verify_authenticity_token加到ApplicationController中,全局生效。

方案2:保留CSRF校验的配置方式

如果需要保留CSRF校验能力,需要完成两步配置:

  1. 配置Rails CORS规则允许前端域名访问
    安装rack-cors gem,在config/initializers/cors.rb中添加如下配置:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://localhost:3000'
    resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
  1. 前端请求携带CSRF令牌
    Rails会默认把CSRF令牌存在名为XSRF-TOKEN的cookie中,前端发送请求时从cookie中读取该值,添加到请求头的X-CSRF-Token字段即可,修改你的fetch请求配置:
const playerPOST = ({
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "Accept": "application/json",
        // 新增CSRF令牌头,可通过js-cookie等库读取cookie中的XSRF-TOKEN值
        "X-CSRF-Token": Cookies.get('XSRF-TOKEN')
    },
    body: JSON.stringify({
        // 建议主动把参数包在player字段下,避免参数包装规则异常导致参数校验失败
        player: {
            atk: playerObj.atk,
            sAtk: playerObj.sAtk,
            def: playerObj.def,
            sDef: playerObj.sDef,
            spd: playerObj.spd,
            hp: playerObj.hp,
            name: playerObj.name
        }
    })
})

内容的提问来源于stack exchange,提问作者user17306847

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:45:03