2011/04/27

devise でカスタム認証ロジックを組み込む

たとえば、退職したユーザにはログインさせたくないけど、表示等の関係でユーザ情報を削除できない場合、users テーブルに can_login 列などを作って、フラグ管理しますよね。
んで can_login 列の値でログインを制御したい場合、どう組み込めばいいかなーと悩んでたんですがとりあえずできたのでエントリにしてみます。
devise やコアとなってる warden にそんな機能はありそうなもんだけど、よくわからなかったので自前で仕込みました。
で、認証を行っているメソッドに追加処理をつっこんでやればいいわけです。
devise の lib/devise/controllers/helpers.rb を見ると、authenticate_user! は warden.authenticate! を、current_user は warden.authenticate を呼びだしてる模様。
warden のソースで lib/warden/proxy.rb を見ると、authenticate! も authenticate も _perform_authentication を呼び出しているので、ここで細工してやればよさそう。
んで、最終的には $RAILS_ROOT/config/initializers/extensions/warden_extension.rb を配置して、中身はこんな感じ。
# -*- coding: utf-8 -*-
module Warden
  class Proxy
    alias_method :original_perform_authentication, :_perform_authentication

    private
    def _perform_authentication(*args)
      user, opts = original_perform_authentication(*args)
      # このチェックを入れないとリダイレクトループになる
      unless winning_strategy && winning_strategy.user
        user = nil if user && !user.can_login?
      end
      [user, opts]
    end
  end
end
元メソッド呼び出したあとに、追加でカスタムロジックを追加している。
んで、その内容自体を元メソッドとして上書きってな感じ。
リダイレクトループにさえならなければ、もっとシンプルなソースになったのに、残念だ。

0 件のコメント :

コメントを投稿