Masahiro Okubo

deviseとdevise token authを共存させる方法

deviseとdevise token authを共存させる方法

qiitaの記事とドキュメントを参考にしながら実装してみました

手順

gemの追加

gem 'devise_token_auth'

反映してdevise token authを追加

bundle install
rails g devise_token_auth:install User auth

マイグレーションファイルは必要なカラムのみでOKなので、こんな感じに修正

class DeviseTokenAuthCreateUsers < ActiveRecord::Migration[6.0]
  def up
    add_column :users, :provider, :string, null: false, default: 'email'
    add_column :users, :uid, :string, null: false, default: ''
    add_column :users, :tokens, :text

    # if your existing User model does not have an existing **encrypted_password** column uncomment below line.
    # add_column :users, :encrypted_password, :null => false, :default => ""

    # the following will update your models so that when you run your migration

    # updates the user table immediately with the above defaults
    User.reset_column_information

    # finds all existing users and updates them.
    # if you change the default values above you'll also have to change them here below:
    User.find_each do |user|
      user.uid = user.email
      user.provider = 'email'
      user.save!
    end

    # to speed up lookups to these columns:
    add_index :users, [:uid, :provider], unique: true
  end

  def down
    # if you added **encrypted_password** above, add here to successfully rollback
    remove_columns :users, :provider, :uid, :tokens
  end
end

initファイルは下記のように修正

# config/initializers/devise_token_auth.rb

DeviseTokenAuth.setup do |config|
  config.change_headers_on_each_request = false # tokenがリクエストごとに変わらないように修正
end

ルーティング追加

通常のdeviseは上にしておく必要があるらしいです

sessionsとregistrationsにはそれぞれskip_actionを入れているので、overrideします

devise_for :users

namespace :api do
    mount_devise_token_auth_for 'User', at: 'auth', controllers: {
        registrations: 'api/auth/registrations',
        sessions: 'api/auth/sessions',
    }
 end

コントローラー情報

# registrations
# frozen_string_literal: true

class Api::Auth::RegistrationsController < DeviseTokenAuth::RegistrationsController
  skip_before_action :verify_authenticity_token

  private

  def sign_up_params
    params.permit(:name, :email, :password, :password_confirmation)
  end

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

# sessions
# frozen_string_literal: true

class Api::Auth::SessionsController < DeviseTokenAuth::SessionsController
  skip_before_action :verify_authenticity_token
end

これで確認してみたところ、無事にアクセスできました。

ちなみにアプリからアクセスしてみたいなーと思ってたので、flutterで試しましたが、特に修正点など必要なくできました。

react nativeのコードもそのまま動くかと思います

参考コードはこちら↓

Rails devise token auth + ReactNative || flutterの雛形コード

参考記事

devise + devise token authでWebにもアプリにも対応
Can I use this gem alongside standard Devise?


関連記事

copyright© 2016-2021 Masahiro Okubo