通过Android登录获取Google OAuth令牌

时间:2015-10-13 13:52:06

标签: android oauth google-signin

我设法按照this article中的说明设置Google登录。我的下一步是使用我自己的服务器对用户进行身份验证,我需要使用Google OAuth令牌。是否可以使用此API检索令牌?

1 个答案:

答案 0 :(得分:0)

这就是我的工作方式。主要警告是在ApiClient抛出UserRecoverableException时显示权限对话框。

public class GoogleAuthenticator implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    /* RequestCode for resolutions involving sign-in */
    private static final int RC_SIGN_IN = 9001;

    /* Keys for persisting instance variables in savedInstanceState */
    private static final String KEY_IS_RESOLVING = "is_resolving";
    private static final String KEY_SHOULD_RESOLVE = "should_resolve";

    /* Is there a ConnectionResult resolution in progress? */
    private boolean mIsResolving = false;
    /* Should we automatically resolve ConnectionResults when possible? */
    private boolean mShouldResolve = false;

    private final Activity mParentActivity;
    private final GoogleApiClient mGoogleApiClient;

    public GoogleAuthenticator(Activity activity) {
        mParentActivity = activity;
        mGoogleApiClient = new GoogleApiClient.Builder(mParentActivity)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Plus.API)
                .addScope(new Scope(Scopes.PROFILE))
                .build();
    }

    @Override
    public void saveInstanceState(Bundle outState) {
        outState.putBoolean(KEY_IS_RESOLVING, mIsResolving);
        outState.putBoolean(KEY_SHOULD_RESOLVE, mShouldResolve);
    }

    @Override
    public void restoreInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            mIsResolving = savedInstanceState.getBoolean(KEY_IS_RESOLVING);
            mShouldResolve = savedInstanceState.getBoolean(KEY_SHOULD_RESOLVE);
        }
    }

    @Override
    public void signIn() {
        mShouldResolve = true;
        mGoogleApiClient.connect();
    }

    @Override
    public void signOut() {
        if (mGoogleApiClient.isConnected()) {
            Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void disconnect() {
        if (mGoogleApiClient.isConnected()) {
            Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
            Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient);
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RC_SIGN_IN) {
            if (resultCode != Activity.RESULT_OK) {
                mShouldResolve = false;
            }

            mIsResolving = false;
            mGoogleApiClient.connect();
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        mShouldResolve = false;
        new GetTokenTask(mParentActivity, mGoogleApiClient).execute();
    }

    @Override
    public void onConnectionSuspended(int i) {}

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        LogUtil.d(TAG, "onConnectionFailed:" + connectionResult);

        if (!mIsResolving && mShouldResolve) {
            if (connectionResult.hasResolution()) {
                try {
                    connectionResult.startResolutionForResult(mParentActivity, RC_SIGN_IN);
                    mIsResolving = true;
                } catch (IntentSender.SendIntentException e) {
                    LogUtil.e(TAG, "Could not resolve ConnectionResult.", e);
                    mIsResolving = false;
                    mGoogleApiClient.connect();
                }
            } else {
                // do something with the error
            }
        } else {
            // do something when logged out
        }
    }

    /**
     * An {@link AsyncTask} to retrieve the auth token for the selected Google account
     */
    private static class GetTokenTask extends AsyncTask<Void, Void, String> {

        private final static String GOOGLE_SCOPES = "oauth2: email profile";
        private final Activity mActivity;
        private final GoogleApiClient mClient;

        private boolean needsFurtherResolution = false;

        public GetTokenTask(Activity activity, GoogleApiClient client) {
            mActivity = activity;
            mClient = client;
        }

        @Override
        protected String doInBackground(Void... params) {
            needsFurtherResolution = false;
            LogUtil.d(TAG, "Executing GetTokenTask...");
            final String accountName = Plus.AccountApi.getAccountName(mClient);
            String token = null;
            try {
                token = GoogleAuthUtil.getToken(mActivity, accountName, GOOGLE_SCOPES, null);
            } catch (IOException e) {
                LogUtil.e(TAG, "Error retrieving ID token.", e);
            } catch (UserRecoverableAuthException e) {
                // This will show the dialog "App needs permission to access..."
                LogUtil.d(TAG, "Launching permissions dialog");
                needsFurtherResolution = true;
                mActivity.startActivityForResult(e.getIntent(), RC_SIGN_IN);
            } catch (GoogleAuthException e) {
                LogUtil.e(TAG, "Error retrieving ID token.", e);
            }
            return token;
        }

        @Override
        protected void onPostExecute(String result) {
            if (!needsFurtherResolution) {
                // do something when token retrieved
            }
        }
    }
}