- Аутентификация OAuth2 в приложении посредством Google Sign-In. Непрерывный доступ к API Google
- Authenticating Your Client
- Using Play App Signing
- Self-signing Your Application
- Using Keytool on the certificate
- Using Keytool on an APK or AAB
- Using Gradle’s Signing Report
- Android apps googleusercontent com
- About
Аутентификация OAuth2 в приложении посредством Google Sign-In. Непрерывный доступ к API Google
«С 20 апреля 2017 года отправка запросов на авторизацию из встроенных браузеров будет блокироваться».
Такое сообщение с 1 марта можно увидеть в некоторых приложениях, где необходима авторизация. Об этом Google написали в своём блоге еще в августе 2016, и это значит, что скоро во многих приложениях придется переписывать реализацию регистрации. Приятного мало, однако выход есть – использовать рекомендуемый способ авторизации Google Sign-in.
Об этом способе и будет идти речь в уроке, а также как получить токены, необходимые для работы с API Google.
В уроке будет присутствовать частичный перевод официальных документаций. Но сперва немного предыстории из моей практики и первой работы с OAuth2, возможно кто-то окажется в похожей ситуации.
Понадобилось мне для приложения получить чат с прямой трансляции YouTube. И тогда я узнала, что для отправки запросов на получение трансляции (и только потом чата) необходимо провести OAuth2 аутентификацию пользователя. Я начала искать. Информации по такой теме очень мало, она разрознена, не подходила для моего случая, и конечно же всё было на английском языке. В основном информация была для работы с наиболее популярными API: Drive, Cloud, Google Plus. В официальной документации API YouTube есть готовый код, бери да пользуйся, однако для Android он не подходит. Потратив немалое количество времени, методом проб и ошибок я пришла к рабочему решению. Первое, что мне захотелось сделать после, это собрать информацию «в кучу» и разложить по полочкам, что и сподвигло на написание этого урока.
Изначально моё решение начиналось с того, что перед пользователем открывался WebView для авторизации (ввод email, пароля). Далее запрашивалось разрешение на использование данных, и только после разрешения в ответе приходил код аутентификации (AuthCode), подробнее что с ним делать будет далее. Url, который открывался в WebView был следующий:
Это ни что иное, как post запрос, в ответ на который приходила страница, содержащая authCode, причем код был в заголовке страницы. Всё, как по рекомендации к API, а действия для сокрытия этого кода от пользователя оставили на разработчика.
Всё работало хорошо, приложение опубликовано, но в один прекрасный день я увидела следующее:
Перейдя по ссылке «Подробнее» попадаем в блог, где сказано, что во имя безопасности, аутентификация через WebView работать не будет с 20 апреля. Ну вот, думаю я, только сделала и придется переделывать через Sign-In. Причем первоначально я пыталась сделать реализацию именно через этот сервис. Однако с уже имеющимися знаниями «что и зачем» получилось довольно быстро. И так, начнем.
1. Получение учетных данных
В Диспетчере API создаем новый проект (или выбираем существующий):
Для авторизации понадобится файл конфигурации, который можно получить в мастере:
Заполняем поля название приложения и пакет. Далее выбираем какой сервис подключаем (Google Sign-In), здесь нужно ввести SHA1 ключ приложения, получить его просто: в Android Studio находим вкладку Gradle, раскрываем вкладки Tasks-android-signingReport. Щелкаем два раза, и в логах появится информация о ключах. Находим ключ SHA1, копируем.
Жмем кнопку «Generate configuration file», а после «Download google-services.json». Этот файл json сохраняем в папку проекта «app».
Важно! Если вы собираетесь публиковать приложение в Google Play, debug ключ SHA1 нужно будет заменить на release ключ, соответственно и заменить файл конфигурации.
Заходим в Диспетчер API, видим, что сгенерировались ключи и идентификаторы клиентов OAuth. Нам понадобятся только данные Web client (идентификатор клиента и секрет клиента).
Во вкладке «Окно запроса доступа 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 и ранее созданный объект опций.
Теперь для запуска авторизации нужна кнопка (либо любой другой элемент). Можно использовать стандартную кнопку Sign In Button. Разметка xml:
Выглядит она так:
В активити кнопка определяется как и все другие view, на нее повешаем слушатель и по клику выполним метод:
Код вызываемого метода представляет собой создание интента и вызов активити для авторизации:
В параметр передаем сконфигурированный mApiClient. RC_AUTH_CODE любое число, как и всегда, для отслеживания результата активити.
При нажатии на копку, будет предложено выбрать аккаунт для входа, либо добавить новый. После выбора, приложение запросит разрешение:
3. Получение Auth code
После того, как пользователь даст разрешение, в onActivityResult получаем данные его аккаунта:
В результате получаем auth code как обычную строку, выглядит он примерно так:
Так же из аккаунта можно получить email пользователя, username и аватарку:
acct.getEmail()
acct.getDisplayName()
acct.getPhotoUrl()
Эти данные могут понадобиться, например, чтобы вставить их в header NavigationView.
4. Получение Access Token и Refresh Token
Получили auth code, теперь его нужно поменять на необходимые для запросов к API токены. Для этого формируем запрос по адресу https://www.googleapis.com/oauth2/v4/token. Например я сделаю это с помощью OkHttp.
Рассмотрим подробнее параметры. В 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 со всеми нужными для работы данными:
«access_token» – токен доступа, ради которого всё проводилось
«expires_in» – время жизни access токена, по умолчанию токен живет 1 час, а в сутки можно получать по запросу 25 токенов, не более.
«token_type» – тип токена, его тоже необходимо запомнить, он также вставляется в запрос к api в дальнейшем.
«refresh_token» – токен для обновления access токена, когда пройдет час жизни. Refresh токен неизменен. Часто на форумах видела проблему, с которой сталкивалась и сама: в запросе не приходил этот токен. Ошибки заключаются в неправильном получении учетных данных, либо неправильные запросы. Если авторизация проводилась через WebView, и в url не указывался такой важный параметр как access_type=offline, то refresh токен попросту не приходил.
5. Обновление Access токена
Час прошел, access токен больше не активен, необходим новый. После этого посыпятся ошибки 401 или 403, сервер скажет, что пользователь не авторизован или не имеет доступа. Запрашивать новое разрешение не годится, если нам нужна непрерывная сессия, например как у меня, нужно непрерывно получать сообщения из чата в течении трансляции, а это несколько часов. Что делать? Посылать запрос на получение нового токена.
Запрос в основном такой же как в пункте 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, чтобы убедиться в правильности ввода параметров и полученных ответах. Я буду очень рада, если кому-то урок окажется полезным!
Источник
Authenticating Your Client
Certain Google Play services (such as Google Sign-in and App Invites) require you to provide the SHA-1 of your signing certificate so we can create an OAuth2 client and API key for your app.
Using Play App Signing
If you’ve published your app using Play App Signing, a requirement when using Android App Bundle, you can get your SHA-1 from the Google Play Console on the Release > Setup > App Integrity page.
Self-signing Your Application
If you’re not using Play App Signing, follow the instructions below to use Keytool or Gradle’s Signing Report to get your SHA-1.
Using Keytool on the certificate
Open a terminal and run the keytool utility provided with Java to get the SHA-1 fingerprint of the certificate. You should get both the release and debug certificate fingerprints.
To get the release certificate fingerprint:
To get the debug certificate fingerprint:
The keytool utility prompts you to enter a password for the keystore. The default password for the debug keystore is android . The keytool then prints the fingerprint to the terminal. For example:
Using Keytool on an APK or AAB
To get the certificate of an application binary:
Using Gradle’s Signing Report
You can also get the SHA-1 of your signing certificate using the Gradle signingReport command:
The signing report will include the signing information for each of your app’s variants:
To learn more about digital signing on Android, see Signing Your Applications.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Источник
Android apps googleusercontent com
Google Sign-In Cordova/PhoneGap Plugin
⚠️ From plugin version 6.0.0 the minimum required cordova-ios version is 4.5.0. Need to use a lower cordova-ios version? Use plugin version 5.3.2 or lower.
This plugin allows you to authenticate and identify users with Google Sign-In on iOS and Android. Out of the box, you’ll get email, display name, given name, family name, profile picture url, and user id. You can also configure it to get an idToken and serverAuthCode.
This plugin only wraps access to the Google Sign-In API. Further API access should be implemented per use-case, per developer.
3. Google API setup
To communicate with Google you need to do some tedious setup, sorry.
It is (strongly) recommended that you use the same project for both iOS and Android.
Before you proceed
Go into your config.xml and make sure that your package name (i.e. the app ID) is what you want it to be. Use this package name when setting up iOS and Android in the following steps! If you don’t, you will likely get a 12501, ‘user cancelled’ error despite never cancelling the log in process.
This step is especially important if you are using a framework such as Ionic to scaffold out your project. When you create the project, the config.xml has a placeholder packagename, e.g. com.ionic.*, so you can start developing right away.
Browser platform require a valid WEB_APPLICATION_CLIENT_ID that generated at Google Developer Console. Ensure you have added your url address (example: http://localhost:3000 ) to Authorized JavaScript origins section. See this screenshot for example
To get your iOS REVERSED_CLIENT_ID , generate a configuration file here. This GoogleService-Info.plist file contains the REVERSED_CLIENT_ID you’ll need during installation. This value is only needed for iOS.
The REVERSED_CLIENT_ID is also known as the «iOS URL Scheme» on the Developer’s Console.
Login on iOS takes the user to a SafariViewController through the Google SDK, instead of the separate Safari browser.
To configure Android, generate a configuration file here. Enable Google Sign-In and add an Android App to add the SHA1 fingerprint. Once Google Sign-In is enabled Google will automatically create necessary credentials in Developer Console for web and Android. There is no need to add the generated google-services.json file into your cordova project. You may need to configure the consent screen.
Make sure you execute the keytool steps as explained here or authentication will fail (do this for both release and debug keystores).
- The step above, about keytool , show 2 types of certificate fingerprints, the Release and the Debug, when generating the configuration file, it’s better to use the Debug certificate fingerprint, after that, you have to go on Google Credentials Manager, and manually create a credential for OAuth2 client with your Release certificate fingerprint. This is necessary to your application work on both Development and Production releases.
- Ensure that you are using the correct alias name while generating the fingerprint.
Login on Android will use the accounts signed in on the user’s device.
Integrating Google Play Services
To set up Google Play Services version, you can use PLAY_SERVICES_VERSION parameter (with 11.8.0 value by default). It is useful in order to avoid conflicts with another plugins which use any other different version of Google Play Service, because they MUST be the same version.
Publishing your app in Google Play Store
Google re-signs your app with a different certificate when you publish it in the Play Store. Once your app is published, copy the SHA-1 fingerprint of the «App signing certificate», found in the «App signing» section under «Release Management», in Google Play Console. Paste this fingerprint in the Release OAuth client ID in Google Credentials Manager.
If you want to get an idToken or serverAuthCode back from the Sign In Process, you will need to pass the client ID for your project’s web application. This can be found on your project’s API credentials page on the Google Developer’s Console.
4. Installation (PhoneGap CLI / Cordova CLI)
This plugin is compatible with:
Here’s how it works (backup your project first!):
Using the Cordova CLI and npm:
Using the Cordova CLI to fetch the latest version from GitHub:
Please note that myreversedclientid is a place holder for the reversed clientId you find in your iOS configuration file. Do not surround this value with quotes. (iOS only Applications)
If you are building a hybrid application (iOS and Android), or an Android application, you have to replace myreversedclientid with the reverse value of Client ID in your Release credential generated on step 3, on Google Developer’s Console, this will be: «com.googleusercontent.apps. uniqueId «, without quotes. Example: ‘123-abc123.apps.googleusercontent.com’ becomes ‘com.googleusercontent.apps.123-abc123’.
myreversedclientid is a place holder for Oauth Client ID specifically generated for web application in your Google Developer’s Console.
GooglePlus.js is brought in automatically. There is no need to change or add anything in your html.
5. Installation (PhoneGap Build)
Add this to your config.xml:
For the (stable) NPM Version:
For the latest version from Git (not recommended):
6. Installation (iOS and Cocoapods)
This plugin use the CocoaPods dependency manager in order to satisfy the iOS Google SignIn SDK library dependencies.
Therefore please make sure you have Cocoapods installed in your iOS build environment — setup instructions can be found here. Also make sure your local Cocoapods repo is up-to-date by running pod repo update .
If building your project in Xcode, you need to open YourProject.xcworkspace (not YourProject.xcodeproj ) so both your Cordova app project and the Pods project will be loaded into Xcode.
You can list the pod dependencies in your Cordova iOS project by installing cocoapods-dependencies:
Check the demo app to get you going quickly, or hurt yourself and follow these steps.
Note that none of these methods should be called before deviceready has fired.
3/31/16: This method is no longer required to be checked first. It is kept for code orthoganality.
The login function walks the user through the Google Auth process. All parameters are optional, however there are a few caveats.
To get an idToken on Android, you must pass in your webClientId (a frequent mistake is to supply Android Client ID). On iOS, the idToken is included in the sign in result by default.
To get a serverAuthCode , you must pass in your webClientId and set offline to true. If offline is true, but no webClientId is provided, the serverAuthCode will NOT be requested.
The default scopes requested are profile and email (always requested). To request other scopes, add them as a space-separated list to the scopes parameter. They will be requested exactly as passed in. Refer to the Google Scopes documentation for info on valid scopes that can be requested. For example, ‘scope’: ‘https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/tasks’ .
Naturally, in order to use any additional scopes or APIs, they will need to be activated in your project Developer’s Console.
The success callback (second argument) gets a JSON object with the following contents, with example data of my Google account:
Additional user information is available by use case. Add the scopes needed to the scopes option then return the info to the result object being created in the handleSignInResult and didSignInForUser functions on Android and iOS, respectively.
On Android, the error callback (third argument) receives an error status code if authentication was not successful. A description of those status codes can be found on Google’s android developer website at GoogleSignInStatusCodes.
On iOS, the error callback will include an NSError localizedDescription.
Try silent login
You can call trySilentLogin to check if they’re already signed in to the app and sign them in silently if they are.
If it succeeds you will get the same object as the login function gets, but if it fails it will not show the authentication dialog to the user.
Calling trySilentLogin is done the same as login , except for the function name.
It is strongly recommended that trySilentLogin is implemented with the same options as login, to avoid any potential complications.
This will clear the OAuth2 token.
This will clear the OAuth2 token, forget which account was used to login, and disconnect that account from the app. This will require the user to allow the app access again next time they sign in. Be aware that this effect is not always instantaneous. It can take time to completely disconnect.
8. Exchanging the idToken
Google Documentation for Authenticating with a Backend Server
As the above articles mention, the idToken can be exchanged for user information to confirm the users identity.
Note: Google does not want user identity data sent directly to a server. The idToken is their preferred method to send that data securely and safely, as it must be verified through their servers in order to unpack.
This has several uses. On the client-side, it can be a way to get doubly confirm the user identity, or it can be used to get details such as the email host domain. The server-side is where the idToken really hits its stride. It is an easy way to confirm the users identity before allowing them access to that servers resources or before exchanging the serverAuthCode for an access and refresh token (see the next section).
If your server-side only needs identity, and not additional account access, this is a secure and simple way to supply that information.
9. Exchanging the serverAuthCode
Google Documentation for Enabling Server-Side Access
As the above articles mention, the serverAuthCode is an item that can be exchanged for an access and refresh token. Unlike the idToken , this allows the server-side to have direct access to the users Google account.
Only in the initial login request serverAuthCode will be returned. If you wish to receive the token a second time, you can by using logout first.
You have a couple options when it comes to this exchange: you can use the Google REST Apis to get those in the hybrid app itself or you can send the code to your backend server to be exchanged there, using whatever method necessary (Google provides examples for Java, Python, and JS/HTTP).
As stated before, this plugin is all about user authentication and identity, so any use of the user’s account beyond that needs to be implemented per use case, per application.
Q: I can’t get authentication to work on Android. And why is there no ANDROID API KEY?
A: On Android you need to execute the keytool steps, see the installation instructions for details.
Q: After following the keytool steps, I still can’t get authentication to work on Android. I’m having a «10 error».
A: You need to get the SHA 1 cert from your apk file. Run: keytool -list -printcert -jarfile and copy the SHA 1 to your Android Client ID on Google Console.
Q: OMG $@#*! the Android build is failing
A: You need to have Android Support Repository and Android Support Library installed in the Android SDK manager. Make sure you’re using a fairly up to date version of those.
Q: Why isn’t this working on my Android Emulator.
A: Make sure you are using a Virtual Device running with a Google APIs target and/or a Google APIs CPU!
Q: I’m getting Error 10, what do I do?
A: This is likely caused by cordova not using the keystore you want to use (e.g. because you generated your own). Please check https://cordova.apache.org/docs/en/latest/guide/platforms/android/#signing-an-app to read how to do this. Some have reported that you need to run cordova clean before running the build to resolve error 10.
Q: I’m getting Error 16, what do I do?
A: This is always a problem because the signature (or fingerprint) of your android app when signed is not added to the google console (or firebase) OAuth whitelist. Please double check if you did everything required for this. See the mini-guide below.
Error 16 & app signing mini-guide
First, make sure you fully read and understand the guide on App Signing from the android documentation!
After/while reading that, double check if you did all steps 1-4 below correctly:
1. Make a keystore
In order to sign your app (on dev or publish) you will need to make a local keystore and key with Android Studio or via terminal. Google has a feature called «Google Play App Signing» where they will keep the key on their server and sign your app for you, but if you use this feature or not, you will need a local keystore and key either way.
- If you do not use «Google Play App Signing» → go to 3A
- If you do use «Google Play App Signing» → go to 3B
2A. Without Google Play App Signing
Your local keystore and key will be your official app signing key.
You will need to whitelist the following key fingerprints (in SHA1 format) in Google OAuth settings:
- android default debug.keystore key
- your own created keystore with its key (for App Signing)
2B. With Google Play App Signing enabled
Your local keystore and key will be your «Upload key» and another key for official «App Signing key» is created and managed by Google.
You need to whitelist the following key fingerprints (in SHA1 format) in Google Oauth settings:
- android default debug.keystore key
- your own created keystore with its key (for Uploading)
- google’s App Signing key
3. Get key fingerprints
Get the above keys’ fingerprints (in SHA1 format) to be able to whitelist them.
For the android default debug.keystore do:
You will see the SHA1 fingerprint for the debug key in terminal. Copy that.
B. App signing or Upload key
For the own created keystore with key (either for 2A or 2B) do:
You will see the SHA1 fingerprint for the debug key in terminal. Copy that.
C. Google’s App signing key
Only when Google Play App Signing is enabled (for 2B). You can find the key Google will use to sign your builds in the Google Play Console.
Requirement: You need to have finished the basic info on your android app and then you need to upload a signed APK for internal testing. Once this is uploaded you will be able to access the following menu:
Go to Release Management > App sigining. There you will see
- «App signing certificate» and SHA-1 fingerprint
- «Upload certificate» and SHA-1 fingerprint
The «Upload» one is (and should be) the same as key B. above. And the «App signing certificate» is the key that Google will use. Copy this one.
4. Whitelist the key fingerprints
Again we have 2 options to whitelist them. Projects that use only the Google Cloud Platform or projects that use Firebase.
A. Google Cloud Platform projects
(In case you also use Firebase, you can skip this step)
- Go to API & Services > credentials
- Create credentials > OAuth client ID
- choose «android» and insert your SHA1
- Repeat this for all keys (2 or 3)
B. Firebase projects
- Go to the console > Projects settings
- Select your Android app at the bottom. (if you don’t have any, add an android app, you can ignore the whole tutorial they give you, it’s irrelevant for Cordova apps)
- Add the finger prints to the «SHA certificate fingerprints» section.
- Double check your Google Cloud console: API & Services > credentials and see that Firebase has added these automatically at the bottom under «OAuth 2.0 client IDs»
About
➕ Cordova plugin to login with Google Sign-In on iOS and Android
Источник