ruby 有人能解释一下为什么:null_session仍然返回这个错误吗?

dwthyt8l  于 2023-04-29  发布在  Ruby
关注(0)|答案(1)|浏览(118)

我是Rails的新手,对protect_from_forge的概念很坚韧理解,从我的理解来看,这个方法使用的是verify_authentication_token来保护路由。我使用的路由是API路由;就像这样:

class ApiController < ActionController::API
  protect_from_forgery with: :null, only: %i[execute]

  before_action :validate_csrf_token, only: %i[execute]

  def execute
  # action here
  end

  private

  def validate_csrf_token
     return true unless request.post?
     token = request.headers['X-CSRF-Token']
     if token.blank? || !valid_authenticity_token?(token, nil)
       render json: { error: 'Invalid CSRF token' }, status: :unprocessable_entity
     end
  end
end

我还有另一个控制器,我用它来从我的Rails应用程序获取令牌

class CsrfTokenController < ApplicationController
  skip_before_action :verify_authenticity_token

  def index
    render json: { csrf_token: form_authenticity_token }
  end
end

我把它发送到我的ApiController。我遇到的第一个问题是这个错误

HTTP Origin header (http://localhost:3020) didn't match request.base_url (http://localhost:3000)

其次,当我执行POST请求时,我发送的令牌无效

error: "Invalid CSRF token"

我可以确认令牌请求是在打印变量时发送回来的请求。
这里有什么我遗漏的吗?或者我理解错了:null_session都错了?
编辑:
由于提及的保护路线的方法不正确而更新

ghhkc1vu

ghhkc1vu1#

CSRF保护所做的是为您提供一定程度的确定性,即请求源自您自己的服务器所呈现的页面。这对于经典的应用程序和API来说是很好的,它们只是为了用JSON填充你自己的单页应用程序。但是如果您创建的API是设计为跨域使用的,也可能是由基于服务器的客户端使用的,那么Rails CSRF保护是无关紧要的,实际上与这些要求完全相反。
方法使用form_authenticity_token来保护路由
不,不是真的。其工作方式是将一个唯一的令牌呈现到页面的HTML中(表单和 meta标记),并将相同的令牌存储在会话中。
由于会话存储在加密的cookie中,我们可以合理地确定它没有被篡改。
当用户提交表单时,控制器检查请求体或X-CSRF-Token头中的令牌,除非它与会话cookie提供的值匹配,否则将引发异常。此令牌应仅在单个请求周期内有效。
由于默认情况下cookie是单域的,因此当您从不同的来源发送请求时,实际上不应该期望它起作用。
参见:

相关问题