Arhn - архитектура программирования

Волшебная ошибка Rails? Создает дубликаты учетных записей пользователей

Мне кажется, что пример колдовского кода, показанный на 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 создаст дубликат записи пользователя?


  • Это не ошибка, но функция, которую вы ищете (добавление аутентификации для существующего пользователя), похоже, не поддерживается Sorcery прямо сейчас. Я хотел бы услышать от любого, у кого есть пример того, как исправить это в приложении. 30.04.2012
  • @ Дэн, тебе повезло? 31.08.2012
  • @ChristianFazzini нам действительно повезло. Я разместил наш подход в этой теме. 30.09.2012

Ответы:



2

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

# 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=>"[email protected]", :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

Я надеюсь, что это решение будет полезно для других.

30.09.2012

3

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

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

Этот метод требует наличия twitter_id в модели пользователя. Вы также можете сделать это наоборот с моделью аутентификации. Такие как:

    @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.

30.08.2012
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..