【问题标题】:ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken): While POSTing a JSON arugments to a Rails ControllerActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):将 JSON 参数发布到 Rails 控制器时
【发布时间】:2021-12-20 12:54:05
【问题描述】:

我正在使用 React/Redux 前端和运行后端的 rails 服务器。我有一个按钮,onClick 将发送触发一个动作,该动作由两个分派和一个提取组成,一个分派之前和一个之后。 fetch 正确地找到了服务器,但我收到了 422 错误,这意味着在接受请求后 Rails 方面存在一些问题。错误如您在标题中看到的那样,ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken)。但是,我将参数设置为 require 一个 player 对象和 permit 正确的属性。 fetch 的操作(我知道它有效)看起来像这样

export default function completeAttributeSelection(playerObj){
    const playerPOST = ({
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Accept": "application/json"
        },
        body: JSON.stringify({
            atk: playerObj.atk,
            sAtk: playerObj.sAtk,
            def: playerObj.def,
            sDef: playerObj.sDef,
            spd: playerObj.spd,
            hp: playerObj.hp,
            name: playerObj.name
        })
    })
    return (dispatch) => {
        dispatch({type: "LOADING"})
        console.log("Domain: " + DOMAIN())
        fetch((DOMAIN() + "/players/update_or_create"), playerPOST)
            .then(resp => resp.json())
            .then(json => {
                console.log(json)
                dispatch({type: "ATTRIBUTE_UPDATE_COMPLETE", payload: json})
            })
    }
}

这是处理请求的控制器:

class PlayersController < ApplicationController

    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 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

由于我没有使用任何秘密、密钥或has_secure_password 之类的任何东西,我正在努力了解究竟是什么被这个赶上了。 我从 Rails 终端得到的全部提示(在长时间的混乱错误之前)如下......

Processing by PlayersController#update_or_create as JSON
  Parameters: {"atk"=>6, "sAtk"=>6, "def"=>5, "sDef"=>9, "spd"=>10, "hp"=>85, "name"=>"test01", "player"=>{"name"=>"test01", "atk"=>6, "def"=>5, "sAtk"=>6, "sDef"=>9, "spd"=>10, "hp"=>85}}
HTTP Origin header (http://localhost:3000) didn't match request.base_url (http://localhost:3006)
Completed 422 Unprocessable Entity in 0ms (ActiveRecord: 0.3ms | Allocations: 394)


  
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

【问题讨论】:

    标签: ruby-on-rails json authentication fetch


    【解决方案1】:

    让这个工作的简短答案是将protect_from_forgery with: :null_session 添加到您的控制器。

    class PlayersController < ApplicationController
      protect_from_forgery with: :null_session
    
      # ...
    end
    

    较长的答案涉及 CSRF 和所谓的真实性令牌。这似乎是一个很好的来源https://blog.nvisium.com/understanding-protectfromforgery

    Cross-Site Request Forgery 是一个严重的漏洞,源于 Web 应用程序对会话标识的信任 在浏览器和服务器之间传递的 cookie。对于更多 CSRF的详细解释,我建议看一下OWASP指南 跨站请求伪造。

    Rails 包含一个用于防止 CSRF 的内置机制, protect_from_forgery,默认情况下包含在 application_controller.rb 生成新应用程序时的控制器。 这个protect_from_forgery 方法利用魔法来确保你的 应用程序免受黑客攻击!

    【讨论】:

      猜你喜欢
      • 2018-11-02
      • 2018-11-27
      • 2011-03-22
      • 2017-04-12
      • 2015-11-23
      • 2017-11-13
      • 2015-05-21
      • 2016-11-14
      • 2019-12-25
      相关资源
      最近更新 更多