環境
- Rails 5.2.3
- devise 4.6.2
- devise_token_auth 1.1.0
ViewとAPIを共用しようとした場合、API利用想定のものもCSRF保護でエラーとなってしまう。
Rails5非APIモードでdevise token authを使用したところ以下のようなエラーが発生する。
Started POST "/api/v1/auth/sign_in" for 172.17.0.1 at 2019-05-18 08:44:58 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by DeviseTokenAuth::SessionsController#create as */*
Parameters: {"email"=>"one@example.com", "password"=>"[FILTERED]", "session"=>{"email"=>"one@example.com", "password"=>"[FILTERED]"}}
HTTP Origin header (chrome-extension://aejoelaoggembcahagimdiliamlcdmfm) didn't match request.base_url (http://192.168.11.176:3000)
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/request_forgery_protection.rb:211:in `handle_unverified_request'
vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/request_forgery_protection.rb:243:in `handle_unverified_request'
vendor/bundle/ruby/2.6.0/gems/devise-4.6.2/lib/devise/controllers/helpers.rb:255:in `handle_unverified_request'
vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/request_forgery_protection.rb:238:in `verify_authenticity_token'
以下のドキュメントの記載のように修正するとJSON形式で送られてくるリクエストについてはCSRF保護を回避して処理することができる。
https://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
class ApplicationController < ActionController::Base
include DeviseTokenAuth::Concerns::SetUserByToken
protect_from_forgery unless: -> { request.format.json? } # 追記部分
end
修正後
$ curl -X POST -H 'Content-Type:application/json' -d '{"email":"one@example.com","password":"MyString"}' http://192.168.11.176:3000/api/v1/auth/sign_in
{"data":{"id":980190962,"email":"one@example.com","provider":"email","uid":"one@example.com"}}