lib/

2009-06-16 6 views
1
のファイルから現在の要求をレールで取得する

すべてのユーザ認証コードをlib/auth.rbという1か所に配置しました。それは次のようになります。lib/

のlib/auth.rb

module Admin 

    def do_i_have_permission_to?(permission) 
    # Code to check all of this goes here 
    end 

end 

私は、アプリケーションヘルパーの一環として、このモジュールを含むので、これらの機能はすべてのビューで使用できます。

application_helper .rb

require 'auth' 
module ApplicationHelper 
    include Admin 
    # other stuff here 
end 

また、アプリの一部としてlicationコントローラ、コントローラは、同様に、関数を呼び出すことができるように:

application.rb

require 'auth' 
class ApplicationController < ActionController::Base 
    include Admin 
end 

これまでのところ、とても良いです。

問題は、私のアプリケーションが通常のWebアプリケーションのようではないということです。具体的には、複数のユーザーが同じコンピューターから同時に(同じブラウザーを使用して)システムにログインすることができます。私はそのIPからログインしているすべての人々を見て行動の認証を行い、すべてがそれを行うことができるなら、それは合格します。

これは、管理者が何かをしたい場合、その管理者はまず他の人をすべてログアウトしなければならないということです。これは面倒です。しかし、私たちは、管理者が行うすべての承認の管理シールを必要としています。だから、私に与えられた提案は、管理者が通常はアクセスできないページにユーザ名/パスワードのコンボを提供できるようにすることでした(例えば、「ユーザの編集」ページにこれらの余分な入力フィールドがあります)。それを確認してください。これは、現在のリクエストパラメータで取得する必要があることを意味します。

Admin::do_i_have_permission_to?(permission) 

私はコントローラーのようにparams [:foo]を使うことはできません。なぜなら、paramsは定義されていないからです。同様にrequest.parameters [:foo]も機能しません。私の検索が明らかにした:

  • 現在の検索パラメータは、現在の要求であり、
  • 現在のリクエストが現在のコントローラであり、
  • 電流コントローラは、現在のディスパッチャであり、かつ
  • I現在のディスパッチャがどこにでも置かれているかどうかわかりません。
  • 私は、この多くのフープを飛び越えているとき、私はおそらくそれが間違っていると感じています。だからそれを行う正しい方法は何ですか?私が検討したオプションは次の通りです:

  • 現在、auth.rbにあるすべての機能をApplicationHelperに移動するだけで、要求にアクセスすることができます。うまくいきますが、ヘルパーの手を抜いてしまいます。
  • すべての機能を他の場所に移動すると、それらのメソッドが表示されます(私には分かりません)
  • 私は何か不足しています。

答えて

4

典型的なRailsアプリケーションでは、認証情報はパラメータではなくアクティブセッションに格納されます。したがって、あなたが望むことをするヘルパーを書くのはかなり簡単です。

ApplicationHelperに含まれるモジュールを作成することは、あまり正統性がないようです。従来のアプローチは、この場合、おそらくAuthenticationHelperと呼ばれる別のヘルパーを作成することです。これを必要なコントローラに含めることもできますし、必要に応じてApplicationControllerにロードして汎用的に使用できるようにすることもできます。

一般的に言えば、ヘルパーは他のヘルパーを含むべきではありません。特定のコントローラーに複数のヘルパーをロードする方が簡単です。

ヘルパーメソッドは、操作中のコントローラコンテキスト内で宣言されたインスタンス変数にフルアクセスできます。具体的には、インスタンス変数(@name)のみであり、ローカル変数(name)ではありません。ヘルパーメソッドは、特定のビューに対しても実行されます。

また、私は、少なくとも従来のWebベースのアプリケーションでは、ユーザーが同じ手順で資格情報を提供して操作を実行する理由がわかりません。通常、このプロセスはログインして別々にアクションを実行することです。

しかし、各トランザクションが独立した操作であるAPIの場合、最も簡単なアプローチは、認証を処理する関連するリクエストパラメータを取り出し、コントローラのインスタンス変数をいくつか設定してから実行を進めることです資格情報が課した制約が与えられた特定の要求

私が通常このようなことに従うアプローチは、必要なチェックを実行できるApplicationController自体の認証構造体にレイヤーを置くことです。これらは保護されたメソッドです。

can_edit_userなどのヒープ全体をロールインするのは魅力的ですが、とcan_create_group?これらは非常に迅速に手を抜く。汎用can_performのフックを入れるのは簡単な設計ですか?またはhas_authority_to?メソッドと必要なパラメータを渡します。例えば

、非常にラフな実装:

class ApplicationController < ActionController::Base 
    protected 
    def has_authority_to?(operation, conditions = { }) 
     AuthenticationCheck.send(operation, conditions) 
    rescue 
     false 
    end 
    end 

    module AuthenticationCheck 
    def self.edit_user?(conditions) 
     session_user == conditions[:user] 
    end 
    end 

    class UserController 
    # ... 

    def edit 
     @user = User.find(params[:id]) 

     unless (has_authority_to?(:edit_user, :user => @user)) 
     render(:partial => 'common/access_denied', :status => :forbidden) 
     end 
    rescue ActiveRecord::RecordNotFound 
     render(:partial => 'users/not_found') 
    end 
    end 

明らかにあなたが繰り返しを避けるためにと一貫性を促進するためにbefore_filterブロックに権限チェックの多くをロールすると思います。私はビューから呼び出し可能であることを、それを望んでいたかので、私はモジュールに機能を分離のだ

http://github.com/theworkinggroup/wristband/tree/master

+0

フルフレームワークの例は、このようなリストバンドのユーザ認証システムとして、より多くの助けになるかもしれませんコントローラ(私はこれをより明確にするために上記を編集しました) 私は示唆したように、前述のすべての機能を備えたauthentication_helper.rbファイルを作成しましたが、他の場所では見えません。 (私のコントローラーに「ヘルパー:認証」を入れても「NoMethodError」が出てきます) これらの機能が必要な理由は、上記で概説したとおりです。どこでも:コントローラ、ビュー、テストなど – Atiaxi

+0

ああ、私のすべてのauthentication_helper.rb関数は、独自のモジュール(AuthenticationHelper)に入っています - 'include AuthenticationHelper'を入れて、 – Atiaxi

+0

コントローラメソッドでもあるヘルパメソッドが必要な場合は、helper_method呼び出しでタグ付けされた保護されたApplicationControllerメソッドのセットが本当に必要です。 例: def is_user_admin? false end helper_method:is_user_admin? – tadman