简体   繁体   English

在Android上重新使用Google+的“一次性授权码”

[英]Regeneration of “one time authorization code” for Google+ on Android

I am working with authenticating via Google+ according to the following: https://developers.google.com/+/mobile/android/sign-in 我正在根据以下内容通过Google+进行身份验证: https//developers.google.com/+/mobile/android/sign-in

Most of this process seems fine. 大多数这个过程似乎很好。 The problem I'm having is that we need to get a "one-time authorization code" so that our backend servers can perform certain requests on behalf of the user, with their permission. 我遇到的问题是我们需要获得“一次性授权代码”,以便我们的后端服务器可以代表用户在他们的许可下执行某些请求。 This is covered in the section "Enable server-side api access for your app". “为您的应用启用服务器端api访问”一节中对此进行了介绍。 However, for a number of reasons, our servers can cause the login to fail, even if the authorization code is valid (eg the user doesn't have an account corresponding to the google+ account on our servers yet, in which case they can make one). 但是,由于多种原因,即使授权代码有效,我们的服务器也可能导致登录失败(例如,用户在我们的服务器上没有与Google +帐户相对应的帐户,在这种情况下,他们可以制作一)。

If this happens, we might need them to login again at a later time. 如果发生这种情况,我们可能需要他们稍后再次登录。 What I'm finding, though, is that when I perform the second login with google+, it gives me the same authorization code , even if it's already been used by our servers. 但我发现,当我使用google +执行第二次登录时,它会给我相同的授权码 ,即使它已被我们的服务器使用过。 I've tried disconnecting and reconnecting to the google client api, and calling GoogleApiClient.clearDefaultAccountAndReconnect() , but no matter what I do, I seem to end up with the same authorization code. 我已经尝试断开连接并重新连接到谷歌客户端API,并调用GoogleApiClient.clearDefaultAccountAndReconnect() ,但无论我做什么,我似乎最终得到相同的授权码。 This, of course, is rejected by the server when it tries to use it, since it's already been used. 当然,当服务器尝试使用它时,它会被拒绝,因为它已被使用。

I'm wondering what I'm doing wrong here. 我想知道我在这里做错了什么。 I have the following method, which is called during the initial authentication process, and then again if a response status of 500 is detected from our server (indicating the previous call failed, presumably because the code has already been used): 我有以下方法,在初始身份验证过程中调用,然后再次从我们的服务器检测到响应状态为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();

So, the answer to this was a lot simpler than I imagined. 所以,答案比我想象的要简单得多。 Apparently, there is a clearToken() method on the GoogleAuthUtil class: 显然, GoogleAuthUtil类上有一个clearToken()方法:

http://developer.android.com/reference/com/google/android/gms/auth/GoogleAuthUtil.html#clearToken%28android.content.Context,%20java.lang.String%29 http://developer.android.com/reference/com/google/android/gms/auth/GoogleAuthUtil.html#clearToken%28android.content.Context,%20java.lang.String%29

public static void clearToken (Context context, String token) public static void clearToken(Context context,String token)

Clear the specified token in local cache with respect to the Context. 根据Context清除本地缓存中的指定标记。 Note that the context must be the same as that used to initialize the token in a previous call to getToken(Context, String, String) or getToken(Context, String, String, Bundle). 请注意,上下文必须与先前调用getToken(Context,String,String)或getToken(Context,String,String,Bundle)时初始化标记的上下文相同。

Parameters 参数

context Context of the token. context令牌的上下文。
token The token to clear. token明确的标记。

Throws 抛出

GooglePlayServicesAvailabilityException
GoogleAuthException
IOException

Calling this method before attempting to re-authenticate causes Google to generate a new one-time authorization token. 在尝试重新进行身份验证之前调用此方法会导致Google生成新的一次性授权令牌。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM