web-dev-qa-db-ja.com

投稿の無効な認証トークン

サインアップ/サインインに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

この動作をわかりやすく説明してください。

16
Imran

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を参照するヘルパーを使用したりすることはできません。

[〜#〜] important [〜#〜]

  • protect_from_forgery with: :null_sessionは、特定の場合にのみ使用する必要があります。たとえば、HTMLフォームなしでAPIリクエスト(POST/PUT/PATCH/DELETE)を許可する場合
  • protect_from_forgery with: :null_sessionを使用すると、承認システムを使用してデータへのアクセスを制限する必要があります。これは、誰でもAPIエンドポイントに対してリクエストを行うことができるためです
  • Htmlフォームを介して行われるリクエストのprotect_from_forgery with: :exceptionを削除しないでください。危険です!http://guides.rubyonrails.org/security.html #cross-site-request-forgery-csrf

(htmlフォームを介した)標準リクエストとAPIリクエストの両方を処理するには、通常、同じリソースに対して2つの異なるコントローラーを設定する必要があります。例:

ルート

Rails.application.routes.draw do
  resources :profiles

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

end

ApplicationController

# 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

ProfilesController

(htmlリクエストの標準コントローラ)

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

  # POST yoursites.com/profiles
  def create
  end
end

Api :: V1 :: ProfilesController

(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

30
NickGnd

取得リクエストには認証トークンがありません。

これを使用してフォームにリクエスト偽造物を追加する必要があります

<%= csrf_meta_tag %> 

そして、javascript経由でアドレス

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