我正在使用devise
注册/。
路由
get 'profile' => 'profile#get_profile'
post 'profile' => 'profile#create_profile'
和 profile_controller
def get_profile
render json: {user: current_user}, status: :ok
end
def create_profile
render json: {user: current_user}, status: :ok
end
GET: http://localhost:3000/user/profile返回预期的输出。然而,
POST 请求会抛出错误消息:
ActionController::InvalidAuthenticityToken in User::ProfileController#create_profile
。
请揭开这种行为的神秘面纱。
答案 0 :(得分:26)
要停用CSRF protection
,您可以像这样编辑ApplicationController
:
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
# ...
end
或禁用特定控制器的CSRF protection
:
class ProfilesController < ApplicationController
skip_before_action :verify_authenticity_token
# ...
end
:null_session
策略清空会话,而不是引发异常,这非常适合API 。由于会话为空,因此您无法使用引用current_user
的{{1}}方法或辅助工具。
重要强>:
session
必须仅在特定情况下使用
例如,允许不带html格式的API请求(POST / PUT / PATCH / DELETE)protect_from_forgery with: :null_session
,您必须使用授权系统限制对数据的访问,因为每个人都可以对您的API端点发出请求protect_from_forgery with: :null_session
,是危险的!(请在此处阅读http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf)要处理标准请求(通过html表单)和API请求,通常必须为同一资源设置两个不同的控制器。示例:
protect_from_forgery with: :exception
Rails.application.routes.draw do
resources :profiles
namespace :api do
namespace :v1 do
resources :profiles
end
end
end
(html请求的标准控制器)
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
end
(API请求的控制器)
# app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
# POST yoursites.com/profiles
def create
end
end
答案 1 :(得分:4)
获取请求没有真实性令牌。
您必须使用此
将伪造内容添加到表单中<%= csrf_meta_tag %>
通过javascript地址
$('meta[name="csrf-token"]')
答案 2 :(得分:-4)
在ApplicationController
(或控制器继承的其他控制器)中,有一行:
protect_from_forgery with: :exception
删除它,CSRF检查将被禁用。