Разработка и Omniauth с использованием Google OAuth2.0, почему новый пользователь не создается? - PullRequest
1 голос
/ 10 марта 2020

Я использую Devise (4.7.1) и omniauth-google-oauth2 (0.8.0) в демонстрационном приложении Rails 5.2 для обработки сторонних регистраций. Я могу правильно войти в систему с использованием данных и создавать новых пользователей без проблем. Но когда я пытаюсь использовать кнопку «войти в Google OAuth2.0», это не работает. Он направляет меня обратно к root, который является частью действия контроллера обратного вызова.

Я просматривал различные руководства в Интернете, касающиеся сбоев CSRF и используемых недействительных учетных данных. Я исправил эти проблемы, но теперь остался тот, который смутил меня. Я получаю сообщение об ошибке:

User Load (0.6ms)  SELECT  "users".* FROM "users" WHERE "users"."provider" = ? AND "users"."uid" = ? ORDER BY "users"."id" ASC LIMIT ?  [["provider", "google_oauth2"], ["uid", "106922203178875367517"], ["LIMIT", 1]]
  ↳ app/models/user.rb:21
   (0.1ms)  begin transaction
  ↳ app/models/user.rb:21
  User Exists (0.7ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", ""], ["LIMIT", 1]]
  ↳ app/models/user.rb:21
   (0.1ms)  rollback transaction

Кажется, что действие по созданию нового пользователя начинается, но останавливается из-за отсутствия сообщения электронной почты в параметрах ha sh, сгенерированных обратным вызовом uri. .

Параметры ha sh выглядят так:

Parameters: {"state"=>"XXXXXXXXXXX", "code"=>"XXXXXXXXXXX", "scope"=>"email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid", "authuser"=>"0", "prompt"=>"consent"}

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

class User < ApplicationRecord

  has_many :comments
  has_many :books, through: :comments

  validates :email, uniqueness: true
  # validates :first_name, presence: {message: "Please enter your first name"}
  # validates :last_name, presence: {message: "Please enter your surname"}
  validates :encrypted_password, presence: true


  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :omniauthable, :omniauth_providers => [:google_oauth2]


  def self.from_omniauth(auth)
  # Either create a User record or update it based on the provider (Google) and the UID  

      where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.token = auth.credentials.token
      user.expires = auth.credentials.expires
      user.expires_at = auth.credentials.expires_at
      user.refresh_token = auth.credentials.refresh_token
    end
  end
end

А контроллер обратных вызовов выглядит следующим образом:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  skip_before_action :verify_authenticity_token
    def google_oauth2
      @user = User.from_omniauth(request.env["omniauth.auth"])
      if @user.persisted?
        sign_in @user, :event => :authentication #this will throw if @user is not activated
        set_flash_message(:notice, :success, :kind => "Google") if is_navigational_format?
      else
        session["devise.google_data"] = request.env["omniauth.auth"]
      end
      redirect_to '/'
     end
  end

Буду очень признателен за любую помощь / руководство по этому вопросу, поскольку я сейчас немного озадачен.

Спасибо:)

1 Ответ

0 голосов
/ 10 марта 2020

Исходя из того, что я вижу в вашем коде, вы создаете пользователя без электронной почты, но у вас есть проверка validates :email, uniqueness: true, которая не будет работать, если вы попытаетесь создать 2 учетные записи.

Не могли бы вы подтвердить это? User.where(email: "").count и дай мне знать. Я думаю, что если оно больше 0, вы не можете зарегистрироваться.

Либо удалите проверку уникальности электронной почты, либо попробуйте получить электронную почту из параметров аутентификации.

Вы можете отладить распечатав журналы ошибок в контроллер обратного вызова

      if @user.persisted?
        sign_in @user, :event => :authentication #this will throw if @user is not activated
        set_flash_message(:notice, :success, :kind => "Google") if is_navigational_format?
      else
        Rails.logger.info(@user.errors.full_messages)
        session["devise.google_data"] = request.env["omniauth.auth"]
      end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...