Вход в Omniauth Facebook перенаправляет на регистрацию, если пользователь существует

Я играю с omniauth-facebook драгоценный камень, чтобы войти в сессию разработки через учетную запись facebook. Когда я нажимаю ссылку "Войти через Facebook", все идет хорошо: создается новая учетная запись, я вхожу и возвращаюсь на домашнюю страницу с сообщением, подтверждающим мой новый сеанс (очень хорошо!).

Проблема: Однако, когда учетная запись уже существует, после нажатия на ссылку я перенаправлен на user/sign_up стр. Я следил за этой документацией из вики Devise. Здесь, здесь, здесь и здесь есть много документации о подобных ошибках. Однако каждое из решений уже реализовано в моем приложении (насколько я могу судить) ИЛИ (в случае с последней ссылкой), похоже, основано на более старой модели конфигурации, которая кажется достаточно отличающейся от вики, которую я Я не уверен, что это применимо.

Мое лучшее предположение, что это как-то связано с контроллером обратных вызовов, как @user.persisted? кажется ложным. Это наводит меня на мысль, что мое определение @user не является правильным. Увидеть ниже:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    logger.debug "Inside facebook"
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.from_omniauth(request.env["omniauth.auth"])
    logger.debug "User is #{@user}"

    if @user.persisted?
      logger.debug "@user.persisted?"
      debugger
      sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
      logger.debug "user exists"
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  def failure
    redirect_to root_path, alert: "Login failed"
  end
end

Кроме того, моя модель пользователя выглядит следующим образом:

class User < ActiveRecord::Base
    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable,
                 :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:facebook]

    def self.from_omniauth(auth)
        where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
            user.provider = Devise.friendly_token[0,20]
            user.email = auth.info.email
            user.password = Devise.friendly_token[0,20]
            user.fname = auth.info.first_name
            user.lname = auth.info.last_name
        end
    end
end

Любые предложения, безусловно, приветствуются! Заранее спасибо.

3 ответа

Попробуйте что-то подобное

class Authentication < ActiveRecord::Base

    belongs_to :user
    # validates :provider, :uid, :presence => true

    def self.from_omniauth(auth)
     authenticate = where(provider: auth[:provider], :uid=>auth[:uid]).first_or_initialize
        if authenticate.user
          authenticate.provider = auth[:provider]
          authenticate.uid =auth[:uid]
        else
            user = User.find_or_initialize_by(:email => email)
            authenticate.provider = auth[:provider]
            user.email = email
            user.first_name = first_name
            user.last_name = last_name
            user.social_image = image
            user.password =  Devise.friendly_token.first(8)
            user.save(validate: false)
            if user.errors.any?
              return user
            else
            authenticate.user_id = user.id
            end
         end
        authenticate.save
        authenticate.user

      end
    end

Попробуй это

  def after_sign_in_path_for(resource)
       super resource
  end

Из того, что я понял, что вы не идете на свою целевую страницу

from_omniauth никогда не находит существующего пользователя Facebook, потому что вы перезаписываете атрибут провайдера:

where(provider: auth.provider, uid: auth.uid).first_or_create do |user|

ищет пользователя с провайдером 'facebook' в этом случае, но ни один не может быть найден:

user.provider = Devise.friendly_token[0,20]

меняет провайдера на какой-то случайный токен

просто удалите эту строку, и она должна работать правильно

Другие вопросы по тегам