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

Rails - Google oauth2 request.env['omniauth.auth'] равен нулю, используя omniauth с несколькими моделями

Я работаю над приложением rails и настраиваю Google OAuth2 с помощью omniauth google oauth2 gem . Есть 2 модели, которые используют devise и omniauth и следуют этому руководству для использования devise с несколькими моделями (от команды devise) не работает.

В настоящее время существует 1 существующая модель, использующая devise, которая использует стратегию всеобщей аутентификации для Facebook. Комплектация этой модели выглядит так

devise :invitable, :database_authenticatable, :registerable,
         :trackable, :validatable, :omniauthable, omniauth_providers: [:facebook, :facebook_access_token]

В отдельной модели я хочу добавить стратегию omniauth для Google (эта модель также использует devise), в которой настроено стандартное устройство.

devise :database_authenticatable,
         :recoverable, :rememberable, :trackable, :validatable

на данный момент в devise.rb настроен omniauth для фейсбука

config.omniauth :facebook, ENV['facebook_app_id'], ENV['facebook_app_secret'], { scope: 'comma,seperated,fields', info_fields: 'comma,seperated,fields' }

а в omniauth.rb есть настройки для гугла

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], 
  {
    scope: 'userinfo.email, userinfo.profile',
    prompt: 'select_account',
    image_aspect_ratio: 'square',
    image_size: 50
  }
end

в routes.rb есть разные маршруты для devise/omniauth

devise_for :users, path: 'users', controllers: {omniauth_callbacks: "users/omniauth_callbacks"} do
    get 'sign_out', to: 'devise/sessions#destroy', as: :destroy_user_session
  end

devise_for :admin_users, path: 'admin/admin_users'

Примечание. В route.rb нет controllers: {omniauth_callbacks: "admin/omniauth_callbacks"} для admin_users, потому что я получаю эту ошибку при загрузке моего сервера.

Please add `devise :omniauthable` to the `AdminUser` model

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

Wrong OmniAuth configuration. If you are getting this exception, it means that either:
1) You are manually setting OmniAuth.config.path_prefix and it doesn't match the Devise one
2) You are setting :omniauthable in more than one model
3) You changed your Devise routes/OmniAuth setting and haven't restarted your server

Текущие настройки в файлах инициализации и route.rb позволяют включить сервер. Поскольку я не могу использовать это так, как показано в руководстве, я использую однократный поток гибридной аутентификации, описанный в руководстве по gem omniauth-google-oauth2. На странице, отображающей это представление, у меня настроен javascript следующим образом.

<script src="https://apis.google.com/js/platform.js?onload=init"></script>
<script type="text/javascript">
function init() {
  gapi.load('auth2', function() {
    // Ready.
    $('.google-login-button').click(function(e) {
      e.preventDefault();
      gapi.auth2.authorize({
        client_id: "SOMEKEY.apps.googleusercontent.com",
        cookie_policy: 'single_host_origin',
        scope: 'email profile',
        response_type: 'code'
      }, function(response) {
        if (response && !response.error) {
          // google authentication succeed, now post data to server.
          jQuery.ajax({type: 'POST', url: '/admin/admin-signin', data: response,
            success: function(data) {
              // response from server
              console.log('********************')
              console.log(data)
              console.log('********************')
            }
          });        
        } else {
          // google authentication failed
          console.log('********************')
          console.log(response)
          console.log('********************')
        }
      });
    });
  });
};
init();
</script>

<div class="authform">
  <a class="google-login-button">Sign in</a>
</div>

и я добавил этот маршрут следующим образом

namespace :admin do 
  ...
  post '/admin-signin', to: 'application#google_oauth2'
end

В настоящее время эта настройка позволяет мне отображать приглашение формы из Google, я могу выбрать свою учетную запись для использования. Как только я выбираю учетную запись для использования, я вижу, что параметры отправляются в действие контроллера, и это выглядит так:

{"code"=>"4/LONGCODEOFSTRINGSANDNUMBERS", 
 "scope"=>"email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid", 
"authuser"=>"1", "hd"=>"COMPANY", "session_state"=>"b0c030e5f1304f58695e19aa29cb73c942ac69b6..163d", 
"prompt"=>"consent", "controller"=>"admin/application", "action"=>"google_oauth2"}

Мое действие контроллера для обработки этого вызова выглядит так

def google_oauth2
  @admin_user = AdminUser.from_omniauth(request.env['omniauth.auth'])

  if @admin_user.persisted?
    flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google'
    sign_in_and_redirect @admin_user, event: :authentication
  else
    session['devise.google_data'] = request.env['omniauth.auth'].except(:extra) 
    redirect_to :back, alert: @admin_user.errors.full_messages.join("\n")
  end
end

Но проблема в том, что request.env['omniauth.auth'] равен нулю, и с ним не отправляются никакие данные. Похоже, у меня может быть пара вариантов

  • Есть ли что-то еще, что мне нужно сделать с моей стороны, чтобы request.env['omniauth.auth'] присутствовал? Есть ли обратный вызов, который я отправляю куда-то еще в Google, чтобы вернуть данные request.env['omniauth.auth']?
  • Реализовать модель omniauthable, которую могут использовать как пользователи, так и пользователи admin_users.

Кто-нибудь видит, что я делаю неправильно, или что можно добавить к этому? Все, что я хочу от google oauth, это этот хеш аутентификации, который должен быть присутствует в request.env['omniauth.auth'].

Спасибо за помощь


Ответы:


1

Это была очень специализированная и изолированная проблема, которая может не слишком помочь кому-то, кто столкнется с этим. Я сделал это приложение внутри организации, у которой были разные ключи Google. Таким образом, решение этой проблемы для меня состояло в том, чтобы использовать правильные ключи. Используемые ранее ключи не удовлетворяли настройкам организации и в результате она не работала. Как только я использовал правильные ключи для этой организации, все заработало нормально.

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

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге 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 , и использованием..

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