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のダッシュボード画面が表示されると思います。
※ログアウトも問題なくできるはずです
以上で完了です。