如何通过电子邮件找到用户,如果没有,将他重定向到注册页面
How to find user by email and if not, redirect him to register page
我使用 Omniauth 和 Omniauth-facebook gems 我想点击按钮,如果找到用户,然后登录。如果没有,将他重定向到注册页面。
到目前为止我只使用经典 login/register:
user.rb:
def self.from_omniauth(auth, role)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
return user
else
registered_user = User.where(:email => auth.info.email).first
if registered_user
registered_user.provider = auth.provider
return registered_user
else
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
if (role == "1")
user.add_role :sportsman
elsif (role == "2")
user.add_role :donor
end
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
end
end
omniauth_callbacks_controller.rb:
def facebook
role = cookies[:role]
# signin = cookies[:signin]
user = User.from_omniauth(request.env["omniauth.auth"], role)
if user.persisted?
flash.notice = "Signed by Facebooku"
sign_in_and_redirect user
else
flash.notice = "Error, try again."
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
此代码有效,但如果用户未注册,它将注册他。但是我在用户自己注册时签署角色。
感谢您的帮助。
因为您已经将用户属性保存到会话中
session["devise.user_attributes"] = user.attributes
那么下面应该已经起作用了:
def self.from_omniauth(auth, role)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
return user
else
# NOTE: because you're searching "email" and not both "email" + "provider", then I assume
# that you want users to have only one shared account between all providers (i.e. if they also sign-in in Google with the exact email as his email in Facebook)
registered_user = User.where(:email => auth.info.email).first
if registered_user
# NOTE: this line doesn't do anything because registered_user is not being "saved"
registered_user.provider = auth.provider
return registered_user
else
# build a new User object (don't save yet!)
return User.new.tap do |u|
u.provider = auth.provider
u.email = auth.info.email
u.uid = uid: auth.uid
u.password = Devise.friendly_token[0,20]
# because I assume you're using "rolify" gem, don't add the roles yet here, because I don't think you can store the "roles" into the session
# add the roles logic in whatever controller you have for user registration
end
end
end
end
然后在您的 user
模型中覆盖 new_with_session
。 new_with_session
由 Devise 在 registrations#new
中自动调用。我们需要设置
我们之前存储在session里面的用户属性omniauth_callbacks#facebook
class User < ApplicationRecord
def self.new_with_session(params, session)
super.tap do |user|
if user_attributes = session['devise.user_attributes']
user.assign(user_attributes)
end
end
end
end
所以我使用简单的参数来获取用户来自哪里:
<script type="text/javascript">
document.cookie = "login=0"
</script>
此代码在 views/devise/registrations/new.html.erb(和 views/devise/sessions/new.html.erb)中,并且是 JavaScript。它告诉我用户是从登录页面(会话文件夹-登录=1)还是从注册页面(注册文件夹-登录=0)进入的。然后我使用此代码来确定用户是否来自登录页面以及他是否尚未注册。如果两个条件都为真,那么他将被重定向到注册页面。简单到我都尴尬了...
def facebook
hash = request.env["omniauth.auth"]
info = hash.info
email = info["email"]
user = User.find_by_email(email)
login = cookies[:login]
if (user == nil && login == "1")
redirect_to new_user_registration_path
else
role = cookies[:role]
user = User.from_omniauth(request.env["omniauth.auth"], role)
if user.persisted?
flash.notice = "Logged in by Facebook"
sign_in_and_redirect user
else
flash.notice = "Error, try again."
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
end
我使用 Omniauth 和 Omniauth-facebook gems 我想点击按钮,如果找到用户,然后登录。如果没有,将他重定向到注册页面。
到目前为止我只使用经典 login/register:
user.rb:
def self.from_omniauth(auth, role)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
return user
else
registered_user = User.where(:email => auth.info.email).first
if registered_user
registered_user.provider = auth.provider
return registered_user
else
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
if (role == "1")
user.add_role :sportsman
elsif (role == "2")
user.add_role :donor
end
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
end
end
omniauth_callbacks_controller.rb:
def facebook
role = cookies[:role]
# signin = cookies[:signin]
user = User.from_omniauth(request.env["omniauth.auth"], role)
if user.persisted?
flash.notice = "Signed by Facebooku"
sign_in_and_redirect user
else
flash.notice = "Error, try again."
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
此代码有效,但如果用户未注册,它将注册他。但是我在用户自己注册时签署角色。
感谢您的帮助。
因为您已经将用户属性保存到会话中
session["devise.user_attributes"] = user.attributes
那么下面应该已经起作用了:
def self.from_omniauth(auth, role)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
return user
else
# NOTE: because you're searching "email" and not both "email" + "provider", then I assume
# that you want users to have only one shared account between all providers (i.e. if they also sign-in in Google with the exact email as his email in Facebook)
registered_user = User.where(:email => auth.info.email).first
if registered_user
# NOTE: this line doesn't do anything because registered_user is not being "saved"
registered_user.provider = auth.provider
return registered_user
else
# build a new User object (don't save yet!)
return User.new.tap do |u|
u.provider = auth.provider
u.email = auth.info.email
u.uid = uid: auth.uid
u.password = Devise.friendly_token[0,20]
# because I assume you're using "rolify" gem, don't add the roles yet here, because I don't think you can store the "roles" into the session
# add the roles logic in whatever controller you have for user registration
end
end
end
end
然后在您的 user
模型中覆盖 new_with_session
。 new_with_session
由 Devise 在 registrations#new
中自动调用。我们需要设置
我们之前存储在session里面的用户属性omniauth_callbacks#facebook
class User < ApplicationRecord
def self.new_with_session(params, session)
super.tap do |user|
if user_attributes = session['devise.user_attributes']
user.assign(user_attributes)
end
end
end
end
所以我使用简单的参数来获取用户来自哪里:
<script type="text/javascript">
document.cookie = "login=0"
</script>
此代码在 views/devise/registrations/new.html.erb(和 views/devise/sessions/new.html.erb)中,并且是 JavaScript。它告诉我用户是从登录页面(会话文件夹-登录=1)还是从注册页面(注册文件夹-登录=0)进入的。然后我使用此代码来确定用户是否来自登录页面以及他是否尚未注册。如果两个条件都为真,那么他将被重定向到注册页面。简单到我都尴尬了...
def facebook
hash = request.env["omniauth.auth"]
info = hash.info
email = info["email"]
user = User.find_by_email(email)
login = cookies[:login]
if (user == nil && login == "1")
redirect_to new_user_registration_path
else
role = cookies[:role]
user = User.from_omniauth(request.env["omniauth.auth"], role)
if user.persisted?
flash.notice = "Logged in by Facebook"
sign_in_and_redirect user
else
flash.notice = "Error, try again."
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
end