Я работаю с аутентификацией через Google+ в соответствии со следующим: https://developers.google.com/+/mobile/android/sign-in
Большая часть этого процесса выглядит нормально. Проблема, с которой я столкнулся, заключается в том, что нам нужно получить «одноразовый код авторизации», чтобы наши внутренние серверы могли выполнять определенные запросы от имени пользователя с его разрешения. Это описано в разделе «Включение доступа API на стороне сервера для вашего приложения». Однако по ряду причин наши серверы могут привести к сбою входа в систему, даже если код авторизации действителен (например, у пользователя еще нет учетной записи, соответствующей учетной записи google+ на наших серверах). , и в этом случае они могут сделать один).
Если это произойдет, нам может понадобиться, чтобы они снова вошли в систему позже. Однако я обнаружил, что когда я выполняю второй вход в систему с помощью Google+, он дает мне тот же код авторизации, даже если он уже использовался нашими серверами. Я пытался отключить и снова подключиться к API-интерфейсу клиента Google и вызвать GoogleApiClient.clearDefaultAccountAndReconnect()
, но независимо от того, что я делаю, я получаю тот же код авторизации. Это, конечно, отвергается сервером, когда он пытается его использовать, так как он уже был использован.
Мне интересно, что я делаю неправильно здесь. У меня есть следующий метод, который вызывается во время первоначального процесса аутентификации, а затем снова, если с нашего сервера обнаруживается статус ответа 500
(указывающий, что предыдущий вызов не удался, предположительно, потому что код уже использовался):
private void dispatchGooglePlusAuthCodeAcquisition() {
AsyncTask<Void, Void, String> authAcquisition = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
Bundle authPreferences = new Bundle();
mUserPermissionNeededForAuthCode = false;
authPreferences.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES,
"");
String scopesString = Scopes.PROFILE;
WhenIWorkApplication app = (WhenIWorkApplication)WhenIWorkApplication.getInstance();
String serverClientID = app.getGoogleOAuthClientIDForPersonalServer();
String scope = "oauth2:server:client_id:" + serverClientID + ":api_scope:" + scopesString;
String code = null;
authPreferences.putBoolean(GoogleAuthUtil.KEY_SUPPRESS_PROGRESS_SCREEN, true);
try {
code = GoogleAuthUtil.getToken(
mActivity,
Plus.AccountApi.getAccountName(mGoogleApiClient),
scope,
authPreferences
);
} catch (IOException transientEx) {
// network or server error, the call is expected to succeed if you try again later.
// Don't attempt to call again immediately - the request is likely to
// fail, you'll hit quotas or back-off.
Log.d(LOGTAG, "Encountered an IOException while trying to login to Google+."
+ " We'll need to try again at a later time.");
} catch (UserRecoverableAuthException e) {
mUserPermissionNeededForAuthCode = true;
// Requesting an authorization code will always throw
// UserRecoverableAuthException on the first call to GoogleAuthUtil.getToken
// because the user must consent to offline access to their data. After
// consent is granted control is returned to your activity in onActivityResult
// and the second call to GoogleAuthUtil.getToken will succeed.
if (!mGooglePlusPermissionActivityStarted) {
mGooglePlusPermissionActivityStarted = true;
mActivity.startActivityForResult(e.getIntent(), RESULT_CODE_AUTH_CODE);
}
} catch (GoogleAuthException authEx) {
// Failure. The call is not expected to ever succeed so it should not be
// retried.
Log.e(LOGTAG, "Unable to authenticate to Google+. Call will likely never"
+ " succeed, so bailing.", authEx);
}
return code;
}
@Override
protected void onPostExecute(String aResult) {
if (aResult != null) {
// We retrieved an authorization code successfully.
if (mAPIAccessListener != null) {
mAPIAccessListener.onAuthorizationCodeGranted(aResult);
}
} else if (!mUserPermissionNeededForAuthCode) {
// If this is the case, then we didn't get authorization from the user, or something
// else happened.
if (mAPIAccessListener != null) {
mAPIAccessListener.onAuthorizationFailed();
}
Log.d(LOGTAG, "Unable to login because authorization code retrieved was null");
}
}
};
authAcquisition.execute();