[英]How to save the request.referrer for facebook omniauth in Rails 4
我的应用程序中有两个Facebook按钮。 一个在users/sign_up
,另一个在/visitors/owner-faq
。 我想保存request.referrer
以便知道用户从哪个页面进行了注册。 我已经为外部注册(使用表单)实现了相同的功能,并且可以正常工作。 现在,我无法为facebook omniauth实现相同的功能 。
码:
#user.rb
def self.from_omniauth(auth)
email = auth.info.email
user = User.find_by_email(email) # first tries to find an existing user who signed up normal way with the same email to sign them in
if user && user.confirmed?
user.provider = auth.provider
user.uid = auth.uid
return user
end
where(provider: auth.provider, uid: auth.uid).first_or_create do |user| # then tries to find the user who authenticated through FB, and if
user.email = auth.info.email # not present, creates that user
user.password = Devise.friendly_token[0,20]
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.social_photo_url = auth.info.image
user.skip_confirmation!
end
end
#users/omniauth_callbacks_controller
def facebook
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
Rails.logger.info(@user.errors.inspect)
redirect_to new_user_registration_url
end
end
#application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :store_referrer_url, :only => [:new]
private
def store_referrer_url
session[:referrer] = URI(request.referer).path
end
end
尝试1:
我设法将request.referrer
这样保存在users/omniauth_callbacks_controller
def facebook
@user = User.from_omniauth(request.env["omniauth.auth"])
@user.referrer_url = session[:referrer] #here
@user.save!
if @user.persisted?
sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
Rails.logger.info(@user.errors.inspect)
redirect_to new_user_registration_url
end
end
但是这里的问题是,当现有用户从另一个页面登录时, referrer_url
的值将被覆盖 。 我不想覆盖referrer_url
。
尝试2:
我试图将request.referrer
保存在from_omniauth(auth)
方法User
模型中,如下所示
def self.from_omniauth(auth)
email = auth.info.email
user = User.find_by_email(email) # first tries to find an existing user who signed up normal way with the same email to sign them in
if user && user.confirmed?
user.provider = auth.provider
user.uid = auth.uid
return user
end
where(provider: auth.provider, uid: auth.uid).first_or_create do |user| # then tries to find the user who authenticated through FB, and if
user.email = auth.info.email # not present, creates that user
user.password = Devise.friendly_token[0,20]
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.social_photo_url = auth.info.image
user.referrer_url = session[:referrer]
user.skip_confirmation!
end
end
但这给了我这个错误
undefined local variable or method `session' for #<Class:0x0000000e1c46f8>
任何建议将大有帮助。
如果希望referrer_url
属性在首次设置后保持不变,则应使用OR Equal运算符,该运算符只会在当前值为nil
或false
设置该值:
@user.referrer_url ||= session[:referrer]
如果我理解正确,那么在注册和登录时都会调用您的facebook
回调,并且该值当然会被覆盖。 设置值后,或等于将防止覆盖该值。
关于尝试2 ,会话哈希仅在控制器和视图中可用,因此您不能在模型中使用它。
另一种可能性 :
您要在store_referrer_url
方法中设置session[:referrer]
, store_referrer_url
方法在new
方法的before_filter
回调中调用。
您的登录很有可能也是使用new
方法进行的(例如,在Devise中,它将在SessionsController
),因此再次调用该回调并覆盖该值(所有Devise控制器都继承自您的ApplicationController
)。 在这种情况下,您可以从ApplicationController
取出before_filter
回调到正在处理RegistrationsController
的控制器(将是带有Devise的RegistrationsController
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.