QA@IT

Devise Gemのauthenticate_の動作を変更したい

3507 PV

現在rails3.2で開発しているのですが、Deviseというログイン制御をするGemのauthenticate_#{mapping}!(opts={})
というメソッドの動作を変更したいのですが、うまくいかず質問させていただきました。

現在の状況を説明させていただくと、
AユーザとBユーザがいるとします。このAとBはそれぞれのブログを持っています。このブログはログインしないと編集等はできないようにしたいです。
そこでログイン制御をしようと:authenticate_user!メソッドを書いたのですが、ログインしないとAのブログは編集できませんが、Bがログインした状態なら(つまり誰でもログインさえすれば)Aのブログが編集できてしまいます。

Blogクラスのソースを書いて、説明させていただくとこうです。

class BlogsController < ApplicationController
  before_filter :authenticate_user!, :except => ["show","index"]

そこでBlogクラスの持ち主であるUserでないと、編集等ができないようにauthenticate_user!のメソッドを再定義(?)しようと以下のようなコードをinitializersに書きました。

module Devise::Controllers::Helpers
  def authenticate_#{mapping}!(opts={})
    binding.pry#付け足したコード。ブレークポイントの様な働きをします。
    opts[:scope] = :#{mapping}
    warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
  end
end

しかしどうもこのbinding.pryが動作していない、つまり再定義できていない様です。

ここで質問なのですが、
なぜauthenticate_user!のメソッドを再定義できないのでしょうか?
そもそもこのようなやり方が、現在の問題に対してのベストな解決法でしょうか?
ご回答いただけるとうれしいです。

  • 回答は出ているので再定義できていない理由だけ説明すると示されたコード内の #{mapping} は mappingという変数の文字列内の展開ではなく、コメントだからです。 -
  • そうだったんですか。てっきりこういう書き方があるのかと思っていました。ありがとうございます。 -

回答

本当にそう書いたのなら、定義されたのは authenticate_user! というメソッドではなく authenticate_ という名前のメソッドだからではないでしょうか。

それはそれとして、 mori_dev さんが指摘しているように「認証」と「認可」と呼ばれる処理は別々に考えた方が良いと思います。
「認可」処理には cancan という gem がよく使われているようです。

編集 履歴 (0)
  • なるほど、認証と認可の違いは認識していませんでした。しかしそうだとすると、deviseでbefore_filter :authenticate_user!, :except => ["show","index"]等と書くのは本来邪道な方法ということになりますか?こういう処理はcancanでやるべきの様に思えました。 -

current_user と ブログの持ち主の比較をする before_filter を書けばすむのではないでしょうか。
「認証」と「認証後の権限管理」を分けて考えるのがコツだと思います。

編集 履歴 (0)
  • 認証と認可の違いを認識していませんでした。勉強になりました、ありがとうございます。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。