Ruby on rails 3 “是什么?”事件=>;:“认证”;做
这个问题其实很简单,但我似乎找不到答案。事实上,有一个解释,但我不明白:Ruby on rails 3 “是什么?”事件=>;:“认证”;做,ruby-on-rails-3,devise,omniauth,Ruby On Rails 3,Devise,Omniauth,这个问题其实很简单,但我似乎找不到答案。事实上,有一个解释,但我不明白: We pass the :event => :authentication to the sign_in_and_redirect method to force all authentication callbacks to be called. 我已经使用与此类似的操作进行了身份验证: def facebook authenticator = UserAuthenticator.new(request.en
We pass the :event => :authentication to the sign_in_and_redirect method
to force all authentication callbacks to be called.
我已经使用与此类似的操作进行了身份验证:
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
我真正想知道的是什么是好的
:event=>:authentication
。我自己跟踪了源代码,这有助于我理解:event=>:authentication
参数是如何工作的。我希望它也能帮助你
那么你的问题是为什么
将:event=>:身份验证传递给sign_in_和_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
然后在Desive中签名定义:
# 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
现在被传递给典狱长#set_user
,那么你的问题就变成为什么了
将:event=>:身份验证传递给sign_in_和_redirect方法,以强制调用所有身份验证回调
选项[:事件]可以是[:设置\用户,:获取,:身份验证]
# 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
传递
:事件=>:身份验证
会导致Warden(底层设备)触发定义为以下内容的任何回调:
Warden::Manager.after_authentication do |user,auth,opts|
# Code triggered by authorization here, for example:
user.last_login = Time.now
end
如果您没有在认证后使用任何回调,并且您确信您的库也没有,那么它对您没有任何直接的用处。因为这是一个身份验证事件,所以我将保留它,现在您已经知道它的潜在用途
# 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
Warden::Manager.after_authentication do |user,auth,opts|
# Code triggered by authorization here, for example:
user.last_login = Time.now
end