Рельсы Колдовство Жук? Создает дубликаты учетных записей пользователей - PullRequest
3 голосов
/ 27 февраля 2012

Пример кода волшебства, показанного на github, мне кажется, что он создает дубликаты учетных записей, если он расширен, чтобы учесть методы множественного входа (в этом весь смысл oauth). Здесь вы можете увидеть, что create_from () будет вызван, если login_from () не удастся выполнить.

GITHUB AT на https://github.com/NoamB/sorcery-example-app/blob/master/app/controllers/oauths_controller.rb

def callback
provider = params[:provider]
begin
if @user = login_from(provider)
  redirect_to root_path, :notice => "Logged in from #{provider.titleize}!"
else
  begin
    @user = create_from(provider)

Изучение исходного кода для create_from во всех случаях будет создана новая запись учетной записи пользователя. Это было бы неправильно, если запись учетной записи пользователя уже существует.

Мой вопрос: какие методы магии следует вызывать при первом подключении к Facebook, если учетная запись пользователя была создана каким-либо другим способом, кроме Facebook. login_from потерпит неудачу, а create_from сгенерирует дубликат записи usser?

Ответы [ 3 ]

3 голосов
/ 13 сентября 2012

Вы можете использовать def create_and_validate_from (поставщик) .

Это будет проверять, если электронная почта пользователя / имя пользователя уже существует.Если это правда, что он будет хранить информацию в сеансе и может быть отображен в форме регистрации.

А если вы хотите добавить какого-либо провайдера в свою учетную запись, вы можете использовать def add_provider_to_user (provider) .

2 голосов
/ 30 сентября 2012

Было получено несколько запросов на ответ на этот вопрос, поэтому я предоставляю ответ, который Энди Мехиа, часть моей команды, в конце концов пришел для ответа на этот вопрос. Мы использовали источник в колдовстве, чтобы адаптировать следующие функции:

# Returns the hash that contains the information that was passed back from Facebook.
# It only makes sense to call this method on the callback action.
#
# Example hash:
# {:user_info=>{:id=>"562515238", :name=>"Andrés Mejía-Posada", :first_name=>"Andrés", :last_name=>"Mejía-Posada", :link=>"http://www.facebook.com/andmej", :username=>"andmej", :gender=>"male", :email=>"andmej@gmail.com", :timezone=>-5, :locale=>"en_US", :verified=>true, :updated_time=>"2011-12-31T21:39:24+0000"}, :uid=>"562515238"}
def get_facebook_hash
  provider = Rails.application.config.sorcery.facebook
  access_token = provider.process_callback(params, session)
  hash = provider.get_user_hash
  hash.merge!(:access_token => access_token.token)
  hash.each { |k, v| v.symbolize_keys! if v.is_a?(Hash) }
end


# Method added to the User Account model class
def update_attributes_from_facebook!(facebook_hash)
  self.first_name             = facebook_hash[:user_info][:first_name] if self.first_name.blank?
  self.last_name              = facebook_hash[:user_info][:last_name]  if self.last_name.blank?
  self.facebook_access_token  = facebook_hash[:access_token]
  self.email                ||= facebook_hash[:user_info][:email]
  unless facebook_authentication?
    authentications.create!(:provider => "facebook", :uid => facebook_hash[:uid])
  end
  self.build_facebook_profile if facebook_profile.blank?
  save!
  self.facebook_profile.delay.fetch_from_facebook! # Get API data
end

Чтобы показать этот код в контексте, я также включил логику из нашего контроллера:

def callback
   provider = params[:provider]
   old_session = session.clone # The session gets reset when we login, so let's backup the data we need
   begin
     if @user = login_from(provider)   # User had already logged in through Facebook before
       restore_session(old_session)   # Cleared during login
     else
       # If there's already an user with this email, just hook this Facebook account into it.
       @user = UserAccount.with_insensitive_email(get_facebook_hash[:user_info][:email]).first
       # If there's no existing user, let's create a new account from scratch.
       @user ||= create_from(provider) # Be careful, validation is turned off because Sorcery is a bitch!
       login_without_authentication(@user)
     end
   @user.update_attributes_from_facebook!(get_facebook_hash)
   rescue ::OAuth2::Error => e
     p e
     puts e.message
     puts e.backtrace
     redirect_to after_login_url_for(@user), :alert => "Failed to login from #{provider.titleize}!"
     return
   end
   redirect_to after_login_url_for(@user)
 end

Надеюсь, это решение поможет другим.

0 голосов
/ 31 августа 2012

Я столкнулся с той же проблемой.Хотя я не нашел прямого решения с помощью Волшебства, я сделал следующее, что, кажется, работает:

    @user = create_from(params[:provider]) do |user|
      User.where(:twitter_id => user.twitter_id).first.blank?
    end

Для этого метода требуется, чтобы у вас было twitter_id в модели User.Вы также можете сделать это с помощью модели аутентификации.Например:

    @user = create_from(params[:provider]) do |user|
      Authentication.where(:uid => user.twitter_id).first.blank?
    end

Если блок возвращает false, он не создает пользователя.Избегание дубликатов.

Обратите внимание, блок для create_from не работает с 0.7.12.Работает с 0.7.13.

...