我正在使用google_aouth2和facebook设计。谷歌似乎并没有与其他人合作。以下是一些例子:
我以正常方式创建一个帐户(没有omniauth) - : - 我尝试使用Facebook登录,但它没有创建新帐户。它只是登录现有帐户(电子邮件相同) - : - 如果我使用Google登录,它会尝试创建新用户并提出此错误'验证失败:电子邮件已经被采取了
我使用Facebook创建帐户 - : - 如果我使用Google登录,它会尝试创建新用户并提出此错误'验证失败:电子邮件已经被采取了
我使用Google创建了一个帐户 - : - 我尝试使用Facebook登录,但它没有创建新帐户。它只需登录现有帐户(电子邮件相同)
如何让Google像Facebook一样工作?使用相同的电子邮件检测现有用户帐户并登录,而不创建具有相同电子邮件的其他用户?
我的user.rb:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable, :omniauthable
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
def self.find_for_oauth(auth, signed_in_resource = nil)
# Get the identity and user if they exist
identity = Identity.find_for_oauth(auth)
# If a signed_in_resource is provided it always overrides the existing user
# to prevent the identity being locked with accidentally created accounts.
# Note that this may leave zombie accounts (with no associated identity) which
# can be cleaned up at a later date.
user = signed_in_resource ? signed_in_resource : identity.user
# Create the user if needed
if user.nil?
# Get the existing user by email if the provider gives us a verified email.
# If no verified email was provided we assign a temporary email and ask the
# user to verify it on the next step via UsersController.finish_signup
email_is_verified = auth.info.email && (auth.info.verified || auth.info.verified_email)
email = auth.info.email if email_is_verified
user = User.where(:email => email).first if email
# Create the user if it's a new registration
if user.nil?
user = User.new(
#name: auth.extra.raw_info.name,
username: auth.info.email,
email: auth.info.email,
#email ? email : "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com",
password: Devise.friendly_token[0,20],
autouser: true
)
if auth.provider == 'google_oauth2'
user.gplus = auth.info.urls.Google
end
user.skip_confirmation!
user.save!
end
end
# Associate the identity with the user if needed
if identity.user != user
identity.user = user
identity.save!
end
user
end
def email_verified?
self.email && self.email !~ TEMP_EMAIL_REGEX
end
end
Identity.rb:
class Identity < ActiveRecord::Base
belongs_to :user
validates_presence_of :uid, :provider
validates_uniqueness_of :uid, :scope => :provider
def self.find_for_oauth(auth)
find_or_create_by(uid: auth.uid, provider: auth.provider)
end
end
omniauth_callbacks_controller.rb:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def self.provides_callback_for(provider)
class_eval %Q{
def #{provider}
@user = User.find_for_oauth(env["omniauth.auth"], current_user)
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: "#{provider}".gsub(/_/," ").split[0...1].join(' ').capitalize) if is_navigational_format?
else
session["devise.#{provider}_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
}
end
[:google_oauth2, :facebook].each do |provider|
provides_callback_for provider
end
def after_sign_in_path_for(resource)
super resource
end
end
答案 0 :(得分:0)
找到答案!在user.rb文件中,它通过访问“auth.verified&#39;来检查电子邮件是否经过Facebook验证。属性。如果已经过验证,它只会收取电子邮件并检查现有帐户。问题是,Google没有提供该属性。因此,如果有人通过Google进行身份验证,我将绕过这样的验证:
if auth.provider == 'google_oauth2'
email = auth.info.email
else
email_is_verified = auth.info.email && (auth.info.verified || auth.info.verified_email)
email = auth.info.email if email_is_verified
end