帖子上的真实性令牌无效

时间:2015-12-13 13:07:23

标签: ruby-on-rails ruby ruby-on-rails-3 devise

我正在使用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

请揭开这种行为的神秘面纱。

3 个答案:

答案 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端点发出请求
  • 请勿通过html表单删除protect_from_forgery with: :null_session是危险的!(请在此处阅读http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf

要处理标准请求(通过html表单)和API请求,通常必须为同一资源设置两个不同的控制器。示例:

路线

protect_from_forgery with: :exception

的ApplicationController

Rails.application.routes.draw do
  resources :profiles

  namespace :api do
    namespace :v1 do
      resources :profiles
    end
  end

end

ProfilesController

(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

阿比:: V1 :: ProfilesController

(API请求的控制器)

# app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController

  # POST yoursites.com/profiles
  def create
  end
end

refereces: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html#method-i-protect_from_forgery

答案 1 :(得分:4)

获取请求没有真实性令牌。

您必须使用此

将伪造内容添加到表单中
<%= csrf_meta_tag %> 

通过javascript地址

$('meta[name="csrf-token"]')

答案 2 :(得分:-4)

ApplicationController(或控制器继承的其他控制器)中,有一行:

protect_from_forgery with: :exception

删除它,CSRF检查将被禁用。