Devise と Devise Token Auth のどちらも並行して利用したいときの実装メモです。
Devise Token Auth とは?
Webの世界ではCookieを使って認証認可を実現するが、ネイティブアプリの世界ではCookieを使用することができない。
ネイティブアプリの世界ではトークンベースで認証機能を実現する。
Railsでは、Devise Token Auth
というGemを使うと、トークンベースの認証を簡単に実現することができる。
Devise と併用する場合の導入手順
Gemfile
に下記内容を追加して、bundle install
gem 'devise'
gem 'devise_token_auth'
gem 'rack-cors'
rails g devise:install
コマンドを叩いて、表示される内容にしたがって諸々設定する
❯❯❯ rails g devise:install
Running via Spring preloader in process 47294
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Some setup you must do manually if you haven't yet:
1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
===============================================================================
rails g devise:views
コマンドを叩くと、認証に必要なViewファイルが生成される
rails g devise_token_auth:install User auth
コマンドを叩く
db/migrate/YYYYMMDDHHIISS_devise_token_auth_create_users.rb
を下記のように修正
class DeviseTokenAuthCreateUsers < ActiveRecord::Migration[5.2]
def change
create_table(:users) do |t|
## Required
t.string :provider, :null => false, :default => "email"
t.string :uid, :null => false, :default => ""
## Database authenticatable
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
t.boolean :allow_password_change, :default => false
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
t.string :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at
## User Info
t.string :name
t.string :username, null: false, default: ""
t.string :image
t.string :email
t.integer :role, null: false, default: 0
## Tokens
t.text :tokens
t.timestamps
end
add_index :users, :username, unique: true
add_index :users, :email, unique: true
add_index :users, [:uid, :provider], unique: true
add_index :users, :reset_password_token, unique: true
add_index :users, :confirmation_token, unique: true
add_index :users, :unlock_token, unique: true
end
end
rails db:migrate
コマンドを叩く
app/controller/application_controller.rb
を以下のように編集する
class ApplicationController < ActionController::Base
protect_from_forgery unless: -> { request.format.json? }
end
config/application.rb
に Rack::Cors
の設定を追加する
module Hoge
class Application < Rails::Application
...
# for devise_token_auth
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '/api/v1/*',
:headers => :any,
:expose => ['access-token', 'expiry', 'token-type', 'uid', 'client'],
:methods => [:get, :post, :options, :delete, :put]
end
end
end
end
config/routes.rb
に以下を追加
Rails.application.routes.draw do
devise_for :users # mount_devise_token_auth_for より先にくるように
namespace :api do
namespace :v1 do
mount_devise_token_auth_for 'User', at: 'auth'
end
end
...
end
app/controllers/api/v1/application_controller.rb
を以下のように修正
module Api
module V1
class ApplicationController < ActionController::API
skip_before_action :verify_authenticity_token
include DeviseTokenAuth::Concerns::SetUserByToken
end
end
end
下記JSONを localhost:5000/api/v1/auth/sign_in
に向けてPOSTすると client, uid, access-token をレスポンスヘッダから取得できる
client, uid, access-token を次のリクエストヘッダに入れればOK