Не удается получить токен доступа oAuth2 для Google Analytics API

Я использую Rails + Garb Gem (Sija Branch) + omniauth-google-oauth2 Gem, и я могу успешно пройти аутентификацию с помощью Google Analytics API и извлечь данные, которые наше приложение генерирует при использовании входа пользователя, например:

Garb::Session.login('USERNAME', '<PASSWORD>')

Затем я могу использовать Garb для подключения к нужному мне профилю Google Analytics, извлекать из него данные и отображать диаграммы на веб-странице. Все работает нормально.

Однако я хочу использовать oAuth2 для аутентификации с помощью Analytics, поэтому мне пришлось установить ветвь Sija для Garb Gem из Github (он поддерживает oAuth2), а также я установил omniauth-google-oauth2 Gem. Теоретически я должен иметь возможность аутентифицироваться, используя следующий код:

Garb::Session.access_token = access_token # an instance of OAuth2::Client

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

1) Я создал проект в консоли Google API и включил Analytics API в разделе Services.

2) Это предоставило мне идентификатор клиента и секрет клиента.

3) Я наткнулся на этот код, который я мог заполнить указанным выше идентификатором и секретом:

client = OAuth2::Client.new(
GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET,
{
    :site          => 'https://accounts.google.com',
    :authorize_url => '/o/oauth2/auth',
    :token_url     => '/o/oauth2/token'
})

4) Затем идет следующий фрагмент кода:

response = OAuth2::AccessToken.new(
    client,
    STORED_TOKEN, {
    refresh_token: STORED_REFRESH_TOKEN,
    expires_at: STORED_EXPIRES_AT
})

5), а затем теоретически подключиться к:

Garb::Session.access_token = response

У меня проблема в том, что у меня нет информации о токене в пункте (4) выше. Мне кажется, что с oAuth2 мне нужно один раз сделать «рукопожатие» и распечатать значения токенов возврата? Возможно, через код Rails, который распечатывает возвращенные значения, а затем вставляет значения токенов в константу в приложении Rails, чтобы я мог использовать их в приведенном выше коде? Я действительно сбит с толку. Как я упоминал ранее, веб-приложение отлично работает с аутентификацией пользователя при входе в систему. Все, что делает веб-приложение, - это аутентификация с помощью аналитики, выборка некоторых данных и рисование диаграммы. Но я застрял в преобразовании его в oAuth2, поскольку я просто не знаю, как получить токен доступа, который ищет Garb Gem. Я также должен отметить, что это Это не общедоступный веб-сайт с аутентификацией нескольких пользователей, это веб-сайт CMS, который подключается к нашим собственным данным Analytics.

Я видел некоторые частичные фрагменты аспектов этого, но не полностью объясненный или рабочий пример. Я был бы очень признателен за любые рекомендации и помощь с этим вопросом.

Спасибо заранее,

JR


person John R    schedule 03.04.2013    source источник


Ответы (3)


Я прошел через это за последние несколько недель, поэтому позвольте мне рассказать, что сработало:

Чтобы использовать Oauth2, вам необходимо получить «токен обновления», который вы используете для «повторной аутентификации» в Google каждый раз, когда вы делаете вызов API. Для этого необходимо выполнить следующие действия:

1) Настройте свою учетную запись в консоли API - https://code.google.com/apis/console/b/0/ (похоже, вы сделали это хорошо) 2) В вашей учетной записи API убедитесь, что у вас есть URI перенаправления, указывающий обратно на ваше приложение:

http://some-url.com/auth/google_oauth2/callback
http://localhost:3000/auth/google_oauth2/callback

Обратите внимание, что Google не позволит вам перезвонить на локальный компьютер как 0.0.0.0:3000 ... поэтому вам нужно явно использовать localhost

3) В вашем файле маршрута привяжите этот URL-адрес перенаправления к действию в контроллере, где вы собираетесь создать проект или аутентификацию.

match '/auth/:provider/callback' => 'authentications#create'

': Provider' просто позволяет вам сопоставлять несколько типов oauth, но вы также можете просто поместить туда 'google_oauth2'.

4) Теперь создайте это действие в своем контроллере.

def create
  auth = request.env["omniauth.auth"] 
  params = request.env["omniauth.params"]
  project = Project.find(params['project_id'])

  Authentication.create(:project_id => project.id, :provider => auth['provider'], :uid => auth['uid'], :access_token => auth['credentials']['refresh_token'])
  flash[:notice] = "Authentication successful."
  redirect_to owner_view_project_path(project)
end

5) Действие контроллера должно получить соответствующие поля из объекта ответа (подробности объекта ответа здесь: https://github.com/zquestz/omniauth-google-oauth2) - в частности, вам нужно получить 'refresh_token' и сохранить его в своем проекте или объекте аутентификации - если вы не добавили 'access_token' атрибут желаемого объекта, сделайте это сейчас с миграцией, затем начните сохранять токен обновления в этот атрибут

6) Теперь, когда вы готовы вызвать эту конкретную аутентификацию и получить для нее данные API, вы можете загрузить этот объект, в котором вы сохранили токен доступа, и использовать его для получения нового сеанса с API Google следующим образом:

  @authentication = Authentications.find(params[:id])

  client = OAuth2::Client.new GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
                                  {
                                    :site => 'https://accounts.google.com',
                                    :authorize_url => "/o/oauth2/auth",
                                    :token_url => "/o/oauth2/token",
                                  }
  response = OAuth2::AccessToken.from_hash(client, :refresh_token => @authentication.access_token).refresh!
  Garb::Session.access_token = response
  @profiles = Garb::Management::Profile.all

Этот код создавал токен доступа OAuth2 (ответ), указав клиента, затем refresh_token и вызвав «обновить!». чтобы получить обновленный токен доступа ... затем используйте этот токен доступа для установления сеанса Garb, затем вызовите все профили для данной учетной записи с помощью Gard :: Management :: Profile.all

Надеюсь, это поможет - дайте мне знать, если у вас есть вопросы!

person Cam Norgate    schedule 11.05.2013
comment
Большое спасибо за подробный ответ. Я действительно заставил это работать, используя тот же самый Rails, но используя cURL для получения токена доступа / обновления. До сих пор мне не разрешалось отвечать на свой вопрос, поэтому я поставлю его в ответе ниже и помечу ваш как правильный. Ура снова! - person John R; 13.05.2013
comment
Я сделал то же самое и получаю эту ошибку *** OAuth2 :: Исключение ошибки: ‹? Xml version = 1.0 encoding = UTF-8?› ‹Error› ‹domain› GData ‹/domain› ‹code› неудовлетворительные разрешения ‹/ code ›‹InternalReason› Недостаточное разрешение ‹/internalReason› ‹/error› ‹/errors› - person RailsEnthusiast; 29.05.2013

Просто примечание о том, что сработало для меня:

Для шагов 3, 4 и 5 я вместо этого использовал cURL для получения токена доступа / обновления. Шаг 6 для меня будет таким же (с использованием ветви Sija в Garb Gem). Итак, используя cURL:

Используя данные, связанные с вашим приложением Google, отправьте POST следующее с помощью cURL:

curl --data "code=<APP_CODE>&redirect_uri=http://localhost:3000/oauth2callback&client_id=<CLIENT_ID>.apps.googleusercontent.com&scope=&client_secret=<CLIENT_SECRET>&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token

Ответ принимает форму:

{
  "access_token" : "<ACCESS_TOKEN>",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "refresh_token" : "<REFRESH_TOKEN>"
}

который вы можете подключить к Garb Gem согласно части 6.

person John R    schedule 13.05.2013

Ответ @CamNorgate действителен.

Если у вас нет «refresh_token» от Omniauth для обратного вызова, убедитесь, что вы правильно инициализируете: google_oauth2

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"],
    { :scope=>"https://www.google.com/m8/feeds, https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile",
      :approval_prompt=>"force", access_type="offline"
    }

end

Не забудьте включить : author_prompt => "force", access_type = "offline", чтобы токен refresh_token был отправлен обратно. refresh_token предоставляется только при первой авторизации пользователя.

person Jean-Nicholas Hould    schedule 31.03.2014