Rails5 ログイン devise token認証

devise_token_authでtoken認証

別の記事で紹介したRails API / React / PostgreSQLで環境構築が終わっているものとします。
[Docker]Rails API / React / PostgreSQL

目的

(参考)

環境

Windows10 for Pro
Docker for Windows

方法

1. Add gem and Bundle install

Gemfileにdeviseによるtoken認証に必要なgemを追記します。

# generate authentification with token base
gem 'devise'
gem 'devise_token_auth'
gem 'bcrypt', '~> 3.1.13'
gem 'rack-cors'

Gemfileを更新したので、dockerでビルドし直す必要があります。

docker-compose build api

2. devise_token_authの設定

次にdevise_token_authの設定を行います。rails g devise_token_auth:install (Model) (Auth)(カッコ内は任意の名称)を実行します。

docker-compose run --rm api rails g devise_token_auth:install User auth

      create  config/initializers/devise_token_auth.rb
      insert  app/controllers/application_controller.rb
        gsub  config/routes.rb
      create  db/migrate/20191026021711_devise_token_auth_create_users.rb
      create  app/models/user.rb

作成されたファイルを編集していきます。
まず、migrate/のxxxxxx_devise_token_auth_create_users.rbを以下のように変更します。

      ## 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

      ## User Info
      t.string :username  <--- User Modelに必要な任意のカラム
      t.string :email

      ## Tokens
      t.json :tokens

      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

修正したらdb:migrateし、データベースにテーブル/カラムを追加します。

docker-compose run --rm api rails db:migrate
== 20191026021711 DeviseTokenAuthCreateUsers: migrating =======================
-- create_table(:users)
   -> 0.0696s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0275s
-- add_index(:users, [:uid, :provider], {:unique=>true})
   -> 0.0235s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0146s
== 20191026021711 DeviseTokenAuthCreateUsers: migrated (0.1362s) ==============

Registration用のControllerを作成します。

docker-compose run --rm api rails g controller api/auth/registrations
Starting lifemap_db_1 ... done                                                                                    create  app/controllers/api/auth/registrations_controller.rb
      invoke  test_unit
      create  test/controllers/api/auth/registrations_controller_test.rb

registrations_controller.rbにSign Up(新規作成)及びユーザ情報更新時のstrong parameterを追記します。

class Api::Auth::RegistrationsController < ApplicationController
    private
      def sign_up_params
        params.permit(:username, :email, :password, :password_confirmation)
      end

      def account_update_params
        params.permit(:username, :email)
      end
end

routes.rbに名前空間及びregistrationsの情報を追記します。

Rails.application.routes.draw do
  namespace :api do
    mount_devise_token_auth_for 'User', at: 'auth', controllers: {
      registrations: 'api/auth/registrations'
    }
  end
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

routesを確認すると、定義した名前空間apiのファルダが起点になっていることがわかります。

$docker-compose run --rm api rake routes
Starting lifemap_db_1 ... done                                                       

                     Prefix Verb    URI Pattern                        Controller#Action
        new_api_user_session GET    /api/auth/sign_in(.:format)        devise_token_auth/sessions#new
            api_user_session POST   /api/auth/sign_in(.:format)        devise_token_auth/sessions#create
    destroy_api_user_session DELETE /api/auth/sign_out(.:format)       devise_token_auth/sessions#destroy
       new_api_user_password GET    /api/auth/password/new(.:format)   devise_token_auth/passwords#new
      edit_api_user_password GET    /api/auth/password/edit(.:format)  devise_token_auth/passwords#edit
           api_user_password PATCH  /api/auth/password(.:format)       devise_token_auth/passwords#update
                             PUT    /api/auth/password(.:format)       devise_token_auth/passwords#update
                             POST   /api/auth/password(.:format)       devise_token_auth/passwords#create
cancel_api_user_registration GET    /api/auth/cancel(.:format)         api/auth/registrations#cancel
   new_api_user_registration GET    /api/auth/sign_up(.:format)        api/auth/registrations#new
  edit_api_user_registration GET    /api/auth/edit(.:format)           api/auth/registrations#edit
       api_user_registration PATCH  /api/auth(.:format)                api/auth/registrations#update
                             PUT    /api/auth(.:format)                api/auth/registrations#update
                             DELETE /api/auth(.:format)                api/auth/registrations#destroy
                             POST   /api/auth(.:format)                api/auth/registrations#create
     api_auth_validate_token GET    /api/auth/validate_token(.:format) devise_token_auth/token_validations#validate_token

確認

1. User新規作成

  • PostmanでPOSTリクエストを確認しました。

  • Powershellからも確認できます。
$ Invoke-WebRequest -Method Post -Body 'username=norihito&email=norihito0626@gmail.com&password=norihito' http://localhost:3000/api/auth

2. Userログイン

ログインした場合、ヘッダにaccess-token, client, uidの情報が返ってきます。
これらはパスワード、ユーザ情報変更やコンテンツ制限に使用します。

3. Userパスワード変更

新規password及びpassword confirmationの他に、PUTのHeadersにtoken情報を追加します。

エラー例

Deviseの継承の漏れ

エラー内容

docker-compose run --rm api rake db:migrate

rake aborted!
NoMethodError: undefined method `devise' for User

修正箇所
https://github.com/lynndylanhurley/devise_token_auth/issues/1276#issuecomment-478866479

class User < ActiveRecord::Base
  extend Devise::Models <-----Devise継承の漏れの可能性
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  include DeviseTokenAuth::Concerns::User
end

DeviseTokenAuthの継承漏れ

エラー内容

#<AbstractController::ActionNotFound: The action 'create' could not be found for Api::Auth::RegistrationsController>"

修正箇所

module Api
    module Auth
        class RegistrationsController < DeviseTokenAuth::RegistrationsController <--DeviseTokenAuth継承されているかどうか。

Trackbleのラカム作成漏れ(Sign In時)

エラー内容

Undefined method current_sign_in_at

修正箇所
下記をmigrate/のxxxxxx_devise_token_auth_create_users.rbに追記すること。
migrateやり直しの場合は、docker-composer exec api db:rollbackを行ってから、マイグレートし直しましょう。

 ## 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

その他

CSRfチェックをしない

class ApplicationController < ActionController::API
        include DeviseTokenAuth::Concerns::SetUserByToken
        skip_before_action :verify_authenticity_token, if: :devise_controller? # <--- APIではCSRFチェックをしない
end

コメントを残す

Scroll to top