2012-02-10 17 views
16

これは実際には非常に単純な質問ですが、答えを見つけることができないようです。 Omniauth Overview on Githubでは、実際に説明があるが、私はそれを得ることはありません:":event =>:authentication"とは何ですか?

def facebook 
    authenticator = UserAuthenticator.new(request.env["omniauth.auth"], current_user) 

    if authenticator.user_authenticated? 
    sign_in_and_redirect authenticator.user, :event => :authentication 
    else 
    session["devise.oauth_data"] = request.env["omniauth.auth"] 
    redirect_to new_user_registration_url 
    end 
end 

私が本当に知りたいすべて:

We pass the :event => :authentication to the sign_in_and_redirect method 
to force all authentication callbacks to be called. 

は、私はすでに認証は、この1と同様の作用を利用して作業してい何が良いです:event => :authenticationですか?

答えて

20

私はちょうど答えを理解するのを手伝いたいと思います。 :event => :authenticationパラメータの仕組みを理解するのに役立つソースコードを自分で追跡しました。それがあなたにも役立つことを願っています。

が通過だから、なぜあなたの質問は次のとおりです。イベント=>:sign_in_and_redirectメソッドへの認証が呼び出されるすべての認証のコールバックを強制します。

次に、定義を追跡できます。

# Sign in a user and tries to redirect first to the stored location and 
# then to the url specified by after_sign_in_path_for. It accepts the same 
# parameters as the sign_in method. 
def sign_in_and_redirect(resource_or_scope, *args) 
    options = args.extract_options! 
    scope = Devise::Mapping.find_scope!(resource_or_scope) 
    resource = args.last || resource_or_scope 
    sign_in(scope, resource, options) 
    redirect_to after_sign_in_path_for(resource) 
end 

、その後の工夫で定義sign_in:

# All options given to sign_in is passed forward to the set_user method in warden. 
# The only exception is the :bypass option, which bypass warden callbacks and stores 
# the user straight in session. This option is useful in cases the user is already 
# signed in, but we want to refresh the credentials in session. 
# 
# Examples: 
# 
# sign_in :user, @user      # sign_in(scope, resource) 
# sign_in @user        # sign_in(resource) 
# sign_in @user, :event => :authentication # sign_in(resource, options) 
# sign_in @user, :bypass => true   # sign_in(resource, options) 
# 
def sign_in(resource_or_scope, *args) 
    options = args.extract_options! 
    scope = Devise::Mapping.find_scope!(resource_or_scope) 
    resource = args.last || resource_or_scope 

    expire_session_data_after_sign_in! 

    if options[:bypass] 
    warden.session_serializer.store(resource, scope) 
    elsif warden.user(scope) == resource && !options.delete(:force) 
    # Do nothing. User already signed in and we are not forcing it. 
    true 
    else 
    warden.set_user(resource, options.merge!(:scope => scope)) 
    end 
end 

わかりましたので、:event => :authenticationが今warden#set_userに渡され

が通過する理由、そして、あなたの質問になる:イベント=>:認証すべての認証コールバックを強制的に呼び出すためにsign_in_and_redirectメソッドに渡します。

# Manually set the user into the session and auth proxy 
# 
# Parameters: 
# user - An object that has been setup to serialize into and out of the session. 
# opts - An options hash. Use the :scope option to set the scope of the user, set the :store option to false to skip serializing into the session, set the :run_callbacks to false to skip running the callbacks (the default is true). 
# 
# :api: public 
def set_user(user, opts = {}) 
    scope = (opts[:scope] ||= @config.default_scope) 

    # Get the default options from the master configuration for the given scope 
    opts = (@config[:scope_defaults][scope] || {}).merge(opts) 
    opts[:event] ||= :set_user 
    @users[scope] = user 

    if opts[:store] != false && opts[:event] != :fetch 
    options = env[ENV_SESSION_OPTIONS] 
    options[:renew] = true if options 
    session_serializer.store(user, scope) 
    end 

    run_callbacks = opts.fetch(:run_callbacks, true) 
    manager._run_callbacks(:after_set_user, user, self, opts) if run_callbacks 

    @users[scope] 
end 

OPTS [:イベントは】そう[:set_user, :fetch, :authentication]

# Hook to _run_callbacks asserting for conditions. 
def _run_callbacks(kind, *args) #:nodoc: 
    options = args.last # Last callback arg MUST be a Hash 

    send("_#{kind}").each do |callback, conditions| 
    invalid = conditions.find do |key, value| 
     value.is_a?(Array) ? !value.include?(options[key]) : (value != options[key]) 
    end 

    callback.call(*args) unless invalid 
    end 
end 

# A callback hook set to run every time after a user is set. 
# This callback is triggered the first time one of those three events happens 
# during a request: :authentication, :fetch (from session) and :set_user (when manually set). 
# You can supply as many hooks as you like, and they will be run in order of decleration. 
# 
# If you want to run the callbacks for a given scope and/or event, you can specify them as options. 
# See parameters and example below. 
# 
# Parameters: 
# <options> Some options which specify when the callback should be executed 
# scope - Executes the callback only if it maches the scope(s) given 
# only - Executes the callback only if it matches the event(s) given 
# except - Executes the callback except if it matches the event(s) given 
# <block> A block where you can set arbitrary logic to run every time a user is set 
# Block Parameters: |user, auth, opts| 
#  user - The user object that is being set 
#  auth - The raw authentication proxy object. 
#  opts - any options passed into the set_user call includeing :scope 
# 
# Example: 
# Warden::Manager.after_set_user do |user,auth,opts| 
#  scope = opts[:scope] 
#  if auth.session["#{scope}.last_access"].to_i > (Time.now - 5.minutes) 
#  auth.logout(scope) 
#  throw(:warden, :scope => scope, :reason => "Times Up") 
#  end 
#  auth.session["#{scope}.last_access"] = Time.now 
# end 
# 
# Warden::Manager.after_set_user :except => :fetch do |user,auth,opts| 
#  user.login_count += 1 
# end 
# 
# :api: public 
def after_set_user(options = {}, method = :push, &block) 
    raise BlockNotGiven unless block_given? 

    if options.key?(:only) 
    options[:event] = options.delete(:only) 
    elsif options.key?(:except) 
    options[:event] = [:set_user, :authentication, :fetch] - Array(options.delete(:except)) 
    end 

    _after_set_user.send(method, [block, options]) 
end 

することができ、:event => :authenticationを渡す

# after_authentication is just a wrapper to after_set_user, which is only invoked 
# when the user is set through the authentication path. The options and yielded arguments 
# are the same as in after_set_user. 
# 
# :api: public 
def after_authentication(options = {}, method = :push, &block) 
    after_set_user(options.merge(:event => :authentication), method, &block) 
end 
12

はワーデン(基礎となる工夫が)で定義された任意のコールバックをトリガーさせる:

Warden::Manager.after_authentication do |user,auth,opts| 
    # Code triggered by authorization here, for example: 
    user.last_login = Time.now 
end 

after_authenticationコールバックを使用しておらず、あなたのライブラリがどちらでもないと確信している場合は、すぐには使用できません。それは認証イベントなので、それが役に立つかもしれないことを知ったので、私はそれを残しておきます。

関連する問題