30歳パパエンジニアのアウトプット帳

30歳に突入した1児のパパエンジニアのブログ

activeadminでログインにDeviseではなくSorceryを利用する

管理画面をサクッと作成できるactiveadminで、ユーザ認証にDeviseではなくSorceryを利用したのでその手順を紹介。

※前提としてactiveadminは導入済みとします

1. sorceryをインストール

Gemfileにsorceryを記述して、bundle install

[Gemfile]
・・・
gem 'sorcery'
・・・

2. sorceryの設定ファイルなどを生成

rails generate sorcery:installを実行


※remember_meなどのsubmodulesも設定したい場合はドキュメントを参照。

※初回のbundle installでpathオプションを指定した人はbundle exec rails generate sorcery:installですよ。念のため初心者の為に補足。

3. db:migrateを実行

手順2. でmigrationファイルが生成されているのでrails db:migrateを実行。

4. 認証関連のController/Viewの作成

DeviseのようにビルドインでControllerやViewはないので、ログインに必要なものを自分で作ります。

※すごく簡易なログイン画面とログイン/ログアウト処理を実装します


  • app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def new
    @user = User.new
  end

  def create
    login(params[:user][:email], params[:user][:password])

    # redirect_toの代わりにsorceryのredirect_back_or_toでもOK
    redirect_to admin_dashboard_path ← admin_dashboard_pathはactiveadminが定義したdashboardへのパス
  end

  def destroy
    logout

    redirect_to new_session_path
  end
end
  • app/views/sessions/new.html.erb
<h2>Log in</h2>

<%= form_for @user, url: sessions_path do |f| %>
  <div>
    <%= f.text_field :email %>
    <%= f.password_field :password %>
  </div>

  <div>
    <%= f.submit "Log in" %>
  </div>
<% end %>


コントローラー作成したのでconfig/routes.rbも設定します。

  • config/routes.rb
Rails.application.routes.draw do
  ActiveAdmin.routes(self)

  resources :sessions, only: %i(new create)
  delete 'sign_out', to: 'sessions#destroy'

  ・・・
end

5. activeadminの設定の変更

sorceryの準備がやっと完了したので、やっとactiveadminとsoceryの連携部分です。

やることはドキュメントにあるとおり、config/initializers/active_admin.rbの設定を行います。


下記のコメントアウトを外してsorcery用の設定をしますです。

  • config.authentication_method
  • config.current_user_method
  • config.logout_link_path
  • config.logout_link_method
   #
   # This setting changes the method which Active Admin calls
   # within the application controller.
-  # config.authentication_method = :authenticate_admin_user!
+  config.authentication_method = :require_login

   # == User Authorization
   #
@@ -86,7 +86,7 @@ ActiveAdmin.setup do |config|
   #
   # This setting changes the method which Active Admin calls
   # (within the application controller) to return the currently logged in user.
-  # config.current_user_method = :current_admin_user
+  config.current_user_method = :current_user

   # == Logging Out
   #
@@ -98,13 +98,13 @@ ActiveAdmin.setup do |config|
   # will call the method to return the path.
   #
   # Default:
-  config.logout_link_path = :destroy_admin_user_session_path
+  config.logout_link_path = :sign_out_path

   # This setting changes the http method used when rendering the
   # link. For example :get, :delete, :put, etc..
   #
   # Default:
-  # config.logout_link_method = :get
+  config.logout_link_method = :delete

   # == Root
   #
・・・

6. root_pathの設定

手順5. まで完了したらhttp://localhost:3000/adminにアクセスしてみましょう。

localhostやポート番号の3000は自身の環境に合わせてください


アクセスすると下記のエラーが発生すると思います。

NameError (undefined local variable or method `root_path' for #<Admin::AlcoholsController:0x0055a9592f3d40>):

tmp/bundler/ruby/2.3.0/gems/sorcery-0.10.3/lib/sorcery/controller.rb:98:in `not_authenticated'
tmp/bundler/ruby/2.3.0/gems/sorcery-0.10.3/lib/sorcery/controller.rb:25:in `require_login'
・・・

これは認証が必要なページに未認証でアクセスした時にsorceryがroot_pathにリダイレクトしようとしているのですが、root_pathが設定されていないのでこのエラーが発生しています。


これを解決するにはconfig/routes.rbでrootの設定をすればいいです。

未認証でアクセスした場合はログイン画面に遷移して欲しいのでログイン画面のアクションを指定します。

  • config/routes.rb
Rails.application.routes.draw do
  ActiveAdmin.routes(self)

  resources :sessions, only: %i(new create)
  delete 'sign_out', to: 'sessions#destroy'

  root to: 'sessions#new'

  ・・・
end

これで、未認証状態でhttp://localhost:3000/adminにアクセスした時にログイン画面へ遷移させることができるようになりました。

【番外】config/routes.rbにrootを設定する以外の方法

上記でconfig/routes.rbにrootを設定する方法を紹介しましたが、rootがログイン画面なのは何かしっくり来ません。(私だけでしょうか?)

そんな場合はapplication_controller.rbのでsorceryが定義したnot_authenticatedをオーバーライドします。


  • app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
   ・・・

  # override sorcery not_authenticated method
  def not_authenticated
    redirect_to new_session_path
  end

  ・・・
end

7. 確認

rails consoleなどでユーザを作成してからログインを行いましょう。ログイン後activeadminのダッシュボード画面が表示されると思います。

※ログアウトも問題なくできるはずです


以上で完了です。