我正在使用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
.
请揭开这种行为的神秘面纱.
要禁用,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
方法或服务助手session
.
重要提示:
protect_from_forgery with: :null_session
必须仅在特定情况下使用,例如,允许API请求(POST/PUT/PATCH/DELETE)而不使用html表单
随着protect_from_forgery with: :null_session
你必须限制与授权系统访问您的数据,因为每个人都可以做的请求对您的API端点
不要删除protect_from_forgery with: :exception
通过html表单完成的请求,这很危险!(请在此处阅读http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf)
要处理标准请求(通过html表单)和API请求,通常必须为同一资源设置两个不同的控制器.例:
Rails.application.routes.draw do resources :profiles namespace :api do namespace :v1 do resources :profiles end end end
# 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
(html请求的标准控制器)
# app/controllers/profiles_controller.rb class ProfilesController < ApplicationController # POST yoursites.com/profiles def create end end
(API请求的控制器)
# app/controllers/api/v1/profiles_controller.rb module Api module V1 class ProfilesController < ApplicationController # To allow only json request protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? } # POST yoursites.com/api/v1/profiles def create end end end end
参考:http: //api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html#method-i-protect_from_forgery