#android #oauth-2.0
#Android #oauth-2.0
Вопрос:
Мне нужно добавить авторизацию OAuth2 в мое приложение. У меня есть только идентификатор клиента, секрет клиента и имя пользователя (email). Мне нужно получить токен. Можете ли вы дать мне несколько советов о том, как это сделать? Библиотека или пример кода?
Ответ №1:
Вы можете использовать AppAuth для авторизации OAuth2.
Смотрите https://github.com/openid/AppAuth-Android для примера.
Ниже приведена сокращенная версия документации AppAuth.
Обзор
Рекомендуется, чтобы собственные приложения использовали поток кода авторизации.
Этот поток фактически состоит из четырех этапов:
- Указание конфигурации службы авторизации.
- Авторизация через браузер, чтобы получить код авторизации.
- Обмен кодом авторизации для получения токена доступа и обновления.
- Использование токена доступа для доступа к службе защищенных ресурсов.
1. Создайте конфигурацию службы авторизации
Сначала создайте конфигурацию службы авторизации, которая будет использоваться на втором и третьем этапах.
AuthorizationServiceConfiguration mServiceConfiguration =
new AuthorizationServiceConfiguration(
Uri.parse("https://example.com/authorize"), // Authorization endpoint
Uri.parse("https://example.com/token")); // Token endpoint
ClientAuthentication mClientAuthentication =
new ClientSecretBasic("my-client-secret"); // Client secret
(Статические клиентские секреты не рекомендуются в собственных приложениях.)
2. Запросить авторизацию и получить код авторизации
Чтобы получить обратный вызов авторизации, определите следующее действие в вашем файле манифеста. (Вам не нужно выполнять это действие. Это действие будет действовать как прокси для вашего запроса на авторизацию.)
<activity
android:name="net.openid.appauth.RedirectUriReceiverActivity"
tools:node="replace">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="com.example"/> <!-- Redirect URI scheme -->
</intent-filter>
</activity>
Создайте и выполните запрос авторизации.
private void authorize() {
AuthorizationRequest authRequest = new AuthorizationRequest.Builder(
mServiceConfiguration,
"my-client-id", // Client ID
ResponseTypeValues.CODE,
Uri.parse("com.example://oauth-callback") // Redirect URI
).build();
AuthorizationService service = new AuthorizationService(this);
Intent intent = service.getAuthorizationRequestIntent(authRequest);
startActivityForResult(intent, REQUEST_CODE_AUTH);
}
Обработайте ответ авторизации.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode != REQUEST_CODE_AUTH) {
return;
}
AuthorizationResponse authResponse = AuthorizationResponse.fromIntent(intent);
AuthorizationException authException = AuthorizationException.fromIntent(intent);
mAuthState = new AuthState(authResponse, authException);
// Handle authorization response error here
retrieveTokens(authResponse);
}
3. Обменяйте код авторизации
private void retrieveTokens(AuthorizationResponse authResponse) {
TokenRequest tokenRequest = response.createTokenExchangeRequest();
AuthorizationService service = new AuthorizationService(this);
service.performTokenRequest(request, mClientAuthentication,
new AuthorizationService.TokenResponseCallback() {
@Override
public void onTokenRequestCompleted(TokenResponse tokenResponse,
AuthorizationException tokenException) {
mAuthState.update(tokenResponse, tokenException);
// Handle token response error here
persistAuthState(mAuthState);
}
});
}
После успешного завершения извлечения токена сохраняйте AuthState
его, чтобы вы могли повторно использовать его при следующем (повторном) запуске приложения.
4. Доступ к службе защищенных ресурсов
Используется performActionWithFreshTokens
для выполнения вызова API с новым токеном доступа. (Это автоматически гарантирует, что токены свежие, и обновляет их при необходимости.)
private void prepareApiCall() {
AuthorizationService service = new AuthorizationService(this);
mAuthState.performActionWithFreshTokens(service, mClientAuthentication,
new AuthState.AuthStateAction() {
@Override
public void execute(String accessToken, String idToken,
AuthorizationException authException) {
// Handle token refresh error here
executeApiCall(accessToken);
}
});
}
Выполните вызов API. ( AsyncTask
Это просто используется для простоты. Возможно, это не лучшее решение для выполнения вызова API.)
private void executeApiCall(String accessToken) {
new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://example.com/api/...") // API URL
.addHeader("Authorization",
String.format("Bearer %s", params[0]))
.build();
try {
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception e) {
// Handle API error here
}
}
@Override
protected void onPostExecute(String response) {
...
}
}.execute(accessToken);
}
Комментарии:
1. Это рекомендуемый подход для Android? Раньше я думал, что мобильные устройства могут использовать веб-браузер устройства по умолчанию в качестве агента пользователя для обработки перенаправления кода и токена. Изменилось ли это в последнее время?
2. AppAuth рекомендован Google. Он использует пользовательские вкладки Chrome для запроса авторизации. Пользовательские вкладки Chrome имеют некоторые преимущества по сравнению с веб-браузером устройства по умолчанию. Например, пользовательская вкладка перекрывает последнюю показанную активность. (Смотрите следующий доклад от Google: youtu.be/DdQTXrk6YTk?t=220 )