[英]How to save the request.referrer for facebook omniauth in Rails 4
I have two facebook buttons in my application. 我的应用程序中有两个Facebook按钮。 One on users/sign_up
and other on /visitors/owner-faq
. 一个在users/sign_up
,另一个在/visitors/owner-faq
。 I want to save the request.referrer
in order to know from which page the user has signed up. 我想保存request.referrer
以便知道用户从哪个页面进行了注册。 I had implemented the same for external signup(which uses a form) and it worked. 我已经为外部注册(使用表单)实现了相同的功能,并且可以正常工作。 Now I'm unable to implement the same for facebook omniauth . 现在,我无法为facebook omniauth实现相同的功能 。
Code: 码:
#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
Attempt #1: 尝试1:
I managed to save the request.referrer
like this in users/omniauth_callbacks_controller
我设法将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
But the problem here is the value of referrer_url
is overwritten when the existing user logs in from another page . 但是这里的问题是,当现有用户从另一个页面登录时, referrer_url
的值将被覆盖 。 I don't want to get the referrer_url
to be overwritten. 我不想覆盖referrer_url
。
Attempt #2: 尝试2:
I tried to save the request.referrer
in the from_omniauth(auth)
method User
model like this 我试图将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
But it gave me this error 但这给了我这个错误
undefined local variable or method `session' for #<Class:0x0000000e1c46f8>
Any suggestions would be greatly helpful. 任何建议将大有帮助。
If you want the referrer_url
property to stay the same after it's first set, you should use the OR Equal operator, that will only set the value if it's currently nil
or false
: 如果希望referrer_url
属性在首次设置后保持不变,则应使用OR Equal运算符,该运算符只会在当前值为nil
或false
设置该值:
@user.referrer_url ||= session[:referrer]
If I understand correctly, your facebook
callback is called both on sign up and login, and of course the value would be overwritten. 如果我理解正确,那么在注册和登录时都会调用您的facebook
回调,并且该值当然会被覆盖。 OR Equals will prevent the value from being overwritten once it's set. 设置值后,或等于将防止覆盖该值。
Regarding Attempt #2 , the session hash is only available in the controller and the view , so you can't use it in the model. 关于尝试2 ,会话哈希仅在控制器和视图中可用,因此您不能在模型中使用它。
Another possibility : 另一种可能性 :
You are setting session[:referrer]
in your store_referrer_url
method which is called in a before_filter
callback on the new
method. 您要在store_referrer_url
方法中设置session[:referrer]
, store_referrer_url
方法在new
方法的before_filter
回调中调用。
Most likely your login is also made with a new
method (for example, with Devise it would be in SessionsController
), so the callback is called again and the value is overwritten (all Devise controllers inherit from your ApplicationController
). 您的登录很有可能也是使用new
方法进行的(例如,在Devise中,它将在SessionsController
),因此再次调用该回调并覆盖该值(所有Devise控制器都继承自您的ApplicationController
)。 In this case, you could take out the before_filter
callback out of the ApplicationController
to the controller where you are handling signing up (would be RegistrationsController
with Devise). 在这种情况下,您可以从ApplicationController
取出before_filter
回调到正在处理RegistrationsController
的控制器(将是带有Devise的RegistrationsController
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.