簡體   English   中英

在Rails中使用Omniauth時,如果該用戶存在並使用其他身份驗證,則Google_omniauth2會創建一個新用戶

[英]When using Omniauth in Rails, Google_omniauth2 creates a new user if the user exists and use different auth

我使用的是google_aouth2和facebook。 Google aouth似乎與其他公司的表現不佳。 這里有些例子 :

  1. 我以正常方式創建了一個帳戶(沒有omniauth) -:-我嘗試使用Facebook登錄,但它沒有創建新帳戶。 它只是登錄到現有帳戶(電子郵件是相同的) -:-如果我使用Google登錄,它將嘗試創建一個新用戶並給出此錯誤“驗證失敗:電子郵件已被接收”

  2. 我使用Facebook創建帳戶-:-如果我使用Google登錄,它會嘗試創建新用戶並給出此錯誤“驗證失敗:電子郵件已被接收”

  3. 我使用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

omn​​iauth_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

找到了答案! 在user.rb文件中,它通過訪問“ auth.verified”屬性來檢查電子郵件是否已由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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM