追記(2019年11月7日)
条件はわかりませんが、おそらくバージョンによってInvalidAuthenticityTokenエラーがでる場合があります。
ActionController::InvalidAuthenticityToken in DeviseTokenAuth::RegistrationsController#create
その場合はprotect_from_forgeryをフォーマットによって変更することで対応しています。
これが正しい方法かなのかはわかりません。誰か教えてください。
class ApplicationController < ActionController::Base
protect_from_forgery unless: -> { request.format.json? }
...
end
Devise Token Authについて
Deviseのユーザー登録機能を利用して、トークンの発行、トークンによる認証を可能にするgemです。
注意点として、
・普通に入れるとAPI専用として作ることになる(/users/sign_inとか使えない)
・(Deviseのみで開発していたアプリへの)後からDevise Token Authを追加することを前提に作られていない
ということで、この二点を解決する方法を調べました。
セットアップ
Gemfileに追加します。あとから追加する場合もこの状態にします。
...
gem 'devise'
gem 'devise_token_auth'
gem 'omniauth'
...
bundle install #または bundle install --path vendor/bundle
Deviseのインストール(運用中の場合はスキップ)
すでにDeviseが入っている場合は不要です。
rails generate devise:install
rails db:migrate
Deviseの詳細なセットアップについては、以下の記事が参考になります。https://qiita.com/cigalecigales/items/f4274088f20832252374
Devise token authのインストール
次に、Devise token authをインストールします。
rails generate devise_token_auth:install User auth
Routeを修正
Rails.application.routes.draw do
# 先にDevise用のルート
devise_for :users
# /api/v1/authでアクセス可能
namespace :api do
scope :v1 do
mount_devise_token_auth_for 'User', at: 'auth'
end
end
end
application_controller.rbを修正
通常のapplicatino_controller.rbに加えて、API用のapplication_controller.rbを作成します。
まずは通常のapplication_controllerを修正
class ApplicationController < ActionController::Base
#include DeviseTokenAuth::Concerns::SetUserByToken # この行を削除
protect_from_forgery with: :exception
before_filter :set_host # この行を追加
def set_host
Rails.application.routes.default_url_options[:host] = request.host_with_port
end
end
Devise Token Auth用のapplication_controller.rbをapi/v1以下に作成
module Api
module V1
class ApplicationController < ActionController::API # Note: here is not ::BASE
include DeviseTokenAuth::Concerns::SetUserByToken
protect_from_forgery with: :null_session
end
end
end
マイグレーションファイルを修正
Devise Token Auth用に生成されたマイグレーションファイルと、通常のDevise導入時に生成されたマイグレーションファイルを比較しながら、被っているものを削除してマイグレーションファイルを調整します。
モデルを修正
class User < ApplicationRecord
include DeviseTokenAuth::Concerns::User #ここだけがDevise Token Auth用
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Initializerを修正
トークンの有効期限などを設定します。
DeviseTokenAuth.setup do |config|
config.enable_standard_devise_support = true
config.default_confirm_success_url = "confirmed"# この行を追加
config.change_headers_on_each_request = false
config.token_lifespan = 1.month
config.headers_names = {:'access-token' => 'access-token',
:'client' => 'client',
:'expiry' => 'expiry',
:'uid' => 'uid',
:'token-type' => 'token-type' }
end
作りながら書いたので、不完全な内容になっているかもしれません。何か問題があれば随時修正します。