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