Аутентифікація oauth2 в додатку за допомогою google sign-in

Аутентифікація OAuth2 в додатку за допомогою Google Sign-In. Безперервний доступ до API Google +24

  • 03.04.17 10:28 •
  • marypodolyak •
  • # 325518 •
  • Хабрахабр •
  • З пісочниці •
  • 3 •
  • 4500

- такий же як Forbes, тільки краще.

Про це способі і йтиметься в уроці, а також як отримати токени, необхідні для роботи з API Google.

В уроці буде присутній частковий переклад офіційних документацій. Але спершу трохи передісторії з моєї практики і першої роботи з OAuth2, можливо хтось виявиться в схожій ситуації.

Знадобилося мені для додатка отримати чат з прямої трансляції YouTube. І тоді я дізналася, що для відправки запитів на отримання трансляції (і тільки потім чату) необхідно провести OAuth2 аутентифікацію користувача. Я почала шукати. Інформації по такій темі дуже мало, вона розрізнена, не підходила для мого випадку, і звичайно ж все було англійською мовою. В основному інформація була для роботи з найбільш популярними API: Drive, Cloud, Google Plus. В офіційній документації API YouTube є готовий код, бери та користуйся, однак для Android він не підходить. Витративши чималу кількість часу, методом проб і помилок я прийшла до робочого рішенням. Перше, що мені захотілося зробити після, це зібрати інформацію «в купу» і розкласти по поличках, що і спонукало на написання цього уроку.


Це ні що інше, як post запит, у відповідь на який приходила сторінка, що містить authCode, причому код був в заголовку сторінки. Все, як за рекомендацією до API, а дії для приховування цього коду від користувача залишили на розробника.

1. Отримання облікових даних

У Диспетчері API створюємо новий проект (або вибираємо існуючий):

Аутентифікація oauth2 в додатку за допомогою google sign-in


Заповнюємо поля назва програми і пакет. Далі вибираємо який сервіс підключаємо (Google Sign-In), тут потрібно ввести SHA1 ключ додатки, отримати його просто: в Android Studio знаходимо вкладку Gradle, розкриваємо вкладки Tasks-android-signingReport. Клацаємо двічі, і в логах з'явиться інформація про ключі. Знаходимо ключ SHA1, копіюємо.

Аутентифікація oauth2 в додатку за допомогою google sign-in


Тиснемо кнопку «Generate configuration file», а після «Download google-services.json». Цей файл json зберігаємо в папку проекту «app».

Важливо! Якщо ви збираєтеся публікувати додаток в Google Play, debug ключ SHA1 потрібно буде замінити на release ключ, відповідно і замінити файл конфігурації.

Заходимо в Диспетчер API, бачимо, що згенерувати ключі та ідентифікатори клієнтів OAuth. Нам знадобляться тільки дані Web client (ідентифікатор клієнта і секрет клієнта).

Аутентифікація oauth2 в додатку за допомогою google sign-in

У вкладці «Вікно запиту доступу OAuth» можна поміняти email і назва продукту - це те, що буде написано, коли буде запитуватися дозвіл «Додаток **** запитує: ...»

2. Налаштування Sign-In клієнта

Щоб отримати доступ до Google Api Client, в файл gradle app потрібно додати в залежності:


І плагін (в кінець файлу):


У файл gradle project в залежності:


Тут найбільший інтерес викликають рядки:

requestServerAuthCode (getString (R.string.server_client_id)) - запитуємо authCode, передаючи параметр ідентифікатор клієнта (весь повністю), який отримали вище.

requestScopes (new Scope ( "***")) - запитуємо необхідну для використовуваного API область / області доступу. Є деякі вже певні області в Scopes, але, якщо потрібної там не знайшлося, можна задати свою, як в моєму випадку. Для користувача буде відображатися як доступ «до чого» хоче отримати додаток.


Тут все по стандарту з документації:

enableAutoManage (this, this) - в параметри передається активують і слухач з'єднання (реалізуємо інтерфейс GoogleApiClient.OnConnectionFailedListener).

addApi (Auth.GOOGLE_SIGN_IN_API, gso) - вказуємо, що використовуємо Sign In api і раніше створений об'єкт опцій.


Виглядає вона так:

У активують кнопка визначається як і всі інші view, на неї повешана слухач і при натисканні виконаємо метод:


У параметр передаємо конфігурований mApiClient. RC_AUTH_CODE будь-яке число, як і завжди, для відстеження результату активують.

Аутентифікація oauth2 в додатку за допомогою google sign-in


3. Отримання Auth code


В результаті отримуємо auth code як звичайний рядок, виглядає він приблизно так:

acct.getEmail ()
acct.getDisplayName ()
acct.getPhotoUrl ()

Ці дані можуть знадобитися, наприклад, щоб вставити їх в header NavigationView.

4. Отримання Access Token і Refresh Token


Розглянемо докладніше параметри. У Request.Builder () Передаємо url за яким отримуємо токени:


У header вказуємо Content-Type:


Зазначаємо, що це метод POST, в нього передаємо body:


Сформований requestBody обов'язково повинен містити параметри:

"Grant_type", "authorization_code" - вказуємо, що передавати будемо auth code
"Client_id", getString (R.string.server_client_id) - параметр є client id, отриманий в диспетчері API
"Client_secret", getString (R.string.client_secret) - секрет клієнта, отриманий в диспетчері API
"Code", authCode - власне отриманий код.

Запит асинхронний, у відповіді отримуємо звичайний json з усіма потрібними для роботи даними:

5. Оновлення Access токена

Запит в основному такий же як в пункті 4, за винятком деяких параметрів:


Тут важливі параметри:

"Grant_type", "refresh_token" - в типі вказуємо що посилаємо refresh токен
"Refresh_token", mRefreshToken - і сам токен

Відповіддю буде json, що містить новий access токен, з яким знову можна звертатися до API:

Для прикладу покажу як виглядає запит до API, а також як я виконую оновлення токена.
Для запиту до API я використовую Retrofit2 + RxAndroid. Так виглядає запит на отримання чату прямої трансляції:


Тут важливо зауважити, що в header по ключу Authorization повинні передаватися тип токена і сам access токен. Тобто так:


Далі роблю запит через RxAndroid, і так як в коллбек onError приходять всілякі помилки, то туди ж приходить помилка HttpException з кодом 401 Unauthorized після закінчення години. Тут же я обробляю її, перевіряю, якщо це та сама помилка, то привожу до відповідного типу, перевіряю чи дійсно це код 401 і виконую метод отримання нового токена, потім повторюю запит.


Так само для перевірки токена існує GET запит:


У відповідь прийдуть дані про токені, якщо він ще активний, або помилка, якщо його час життя минув.

Знову ж, реалізацію поновлення токена Google залишає на розробника.

Рекомендую перед початком роботи перевіряти запити в сторонньому додатку / розширенні, наприклад Postman, щоб переконатися в правильності введення параметрів і отриманих відповідях. Я буду дуже рада, якщо комусь урок виявиться корисним!

Посилання на використовувану документацію:

Схожі статті