サインアップ/サインインに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
を参照するヘルパーを使用したりすることはできません。
[〜#〜] important [〜#〜]:
protect_from_forgery with: :null_session
は、特定の場合にのみ使用する必要があります。たとえば、HTMLフォームなしでAPIリクエスト(POST/PUT/PATCH/DELETE)を許可する場合protect_from_forgery with: :null_session
を使用すると、承認システムを使用してデータへのアクセスを制限する必要があります。これは、誰でもAPIエンドポイントに対してリクエストを行うことができるためです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
# 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
取得リクエストには認証トークンがありません。
これを使用してフォームにリクエスト偽造物を追加する必要があります
<%= csrf_meta_tag %>
そして、javascript経由でアドレス
$('meta[name="csrf-token"]')