ダメでしょ!

プログラミングとか怒られた話とか…

rails でログイン認証されていない場合にログイン画面へ遷移させる方法(と、Active Admin を利用して管理画面を作成する際に除外する方法)

ログイン認証チェックを全画面に対応させる

./app/controllers/application_controller.rb に以下の様な形で認証チェックを入れます。

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

  before_action :user_logged_in?

  def user_logged_in?
    if session[:user_id]
      begin
        @current_user = User.find_by(user_id: session[:user_id])
      rescue ActiveRecord::RecordNotFound
        reset_user_session
      end
    end
    return if @current_user
    # @current_userが取得できなかった場合はログイン画面にリダイレクト
    flash[:referer] = request.fullpath
    redirect_to login_index_path
  end
  
  def reset_user_session
    session[:user_id] = nil
    @current_user = nil
  end
end

まず、before_action :user_logged_in?の部分ですが、これでどのコントローラが呼び出された時でも、user_logged_in?メソッドが呼び出されることになります。
で、user_logged_in?では、認証情報の有無を確認することでログインしている場合とログインしていない場合の処理を分岐させます。
(上記の例ではsession[:user_id]を認証情報として利用しています。)

このままだと、ログイン画面でもこのチェックが行われてしまうため、ログインコントローラは除外する必要があります。
それは./app/controllers/login_controller.rbに以下のように追記します。(login_controller.rb は、名前はもちろん任意です。)

# ./app/controllers/login_controller.rb
class LoginController < ApplicationController
  skip_before_action :user_logged_in? <-この部分を追記
  ・・・
end

これにより、ログインコントローラ内では、認証チェックがスキップされます。

Active Admin で除外するには

で、今回、Active Admin という管理画面系のgemを利用したのですが、なにも考えずに導入したら、Active Admin が生成する管理者ログイン画面を表示する際にも、認証チェックが発生してしまって、利用者ログイン画面が表示されました。
これはまずいので、Active Admin 側では、ログイン画面と同じように認証チェックをスキップしたいと考えました。
application.rbに認証チェックを入れるのではなく、個々のコントローラに認証チェックを入れれば解決するのですが、それは今後コントローラが追加されることを考えるとうまい解決にはなりません。
で、結局どのようにするか。
ActiveAdmin にはコンフィグが用意されているのですが、このコンフィグ(./config/initializers/active_admin.rb)内に以下のように追加します。

# ./config/initializers/active_admin.rb
ActiveAdmin.setup do |config|
・・・
end

ActiveAdmin::BaseController.class_eval do
  skip_before_action :user_logged_in?
end

これで Active Admin 内では認証処理を行わなくなるため、 Active Admin 側の別の認証処理に認証を任せることができます。

[参考] 管理画面系gem administrate

今回の案件で管理画面が必要になり、改めて管理画面系の gem を探してみたところ、 administrate という gem が見た目シンプルでよさそうだったのですが、時間がなかったため今回は利用経験のあった Active Admin を使うことにしました。
時間ができた時に使ってみたいと思います。