【问题标题】:Can't get the Authorization code from GoogleAuthUtil.getToken()无法从 GoogleAuthUtil.getToken() 获取授权码
【发布时间】:2016-01-17 06:26:49
【问题描述】:

我正在尝试在我的 Android 应用中实现 Google 登录。 我遵循了谷歌的指导方针 https://developers.google.com/identity/sign-in/android/sign-in?configured=truehttps://developers.google.com/identity/protocols/CrossClientAuth

我想从 google 获取授权码,然后将其发送回我的服务器,以便服务器可以处理代码并将其发送给 google 以获取访问令牌。

public static final String TAG = LoginActivity.class.getSimpleName();

    private ProgressDialog loginDialog;

    /* Request code used to invoke sign in user interactions. */
    private static final int RC_SIGN_IN = 1;

    /* RequestCode for resolutions to get GET_ACCOUNTS permission on M */
    private static final int RC_PERM_GET_ACCOUNTS = 2;

    /* Client used to interact with Google APIs. */
    private GoogleApiClient mGoogleApiClient;

    /* Is there a ConnectionResult resolution in progress? */
    private boolean mIsResolving = false;

    /* Should we automatically resolve ConnectionResults when possible? */
    private boolean mShouldResolve = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        // Build GoogleApiClient with access to basic profile
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Plus.API)
                .addScope(new Scope(Scopes.PROFILE))
                .addScope(new Scope(Scopes.EMAIL))
                .addScope(new Scope(Scopes.PLUS_LOGIN))
                .build();

        findViewById(R.id.sign_in_button).setOnClickListener(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnected(Bundle bundle) {
        // onConnected indicates that an account was selected on the device, that the selected
        // account has granted any requested permissions to our app and that we were able to
        // establish a service connection to Google Play services.
        Log.d(TAG, "onConnected:" + bundle);
        mShouldResolve = false;

        new GetIdTokenTask().execute();

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.sign_in_button) {
            onSignInClicked();
        }
    }

    private void onSignInClicked() {
        // User clicked the sign-in button, so begin the sign-in process and automatically
        // attempt to resolve any errors that occur.
        mShouldResolve = true;
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // Could not connect to Google Play Services.  The user needs to select an account,
        // grant permissions or resolve an error in order to sign in. Refer to the javadoc for
        // ConnectionResult to see possible error codes.
        Log.d(TAG, "onConnectionFailed:" + connectionResult);

        if (!mIsResolving && mShouldResolve) {
            if (connectionResult.hasResolution()) {
                try {
                    connectionResult.startResolutionForResult(this, RC_SIGN_IN);
                    mIsResolving = true;
                } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG, "Could not resolve ConnectionResult.", e);
                    mIsResolving = false;
                    mGoogleApiClient.connect();
                }
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);

        if (requestCode == RC_SIGN_IN) {
            // If the error resolution was not successful we should not resolve further.
            if (resultCode != RESULT_OK) {
                mShouldResolve = false;
            }

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

    private class GetIdTokenTask extends AsyncTask<Void, String, String> {

        @Override
        protected String doInBackground(Void... params) {
            String accountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
            Account account = new Account(accountName, GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
            String code = "";
            String sc = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.login";

            String SERVER_CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYY.apps.googleusercontent.com";

            String scope = "oauth2:server:client_id:" + CLIENT_ID + ":api_scope:" + sc;
            try {
                code = GoogleAuthUtil.getToken(getApplicationContext(), account, scope);

            } catch (IOException e) {
                Log.e(TAG, "Error retrieving ID token.", e);
                return null;
            } catch (GoogleAuthException e) {
                Log.e(TAG, "Error retrieving ID token.", e);
                return null;
            }
            return code;
        }

        @Override
        protected void onPostExecute(String result) {
            Log.i(TAG, "ID token: " + result);
            if (result != null) {
                // Successfully retrieved ID Token
                HttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost("https://example.com/auth/google_oauth2/callback");

                try {
                    List nameValuePairs = new ArrayList(1);
                    nameValuePairs.add(new BasicNameValuePair("idToken", result));
                    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                    HttpResponse response = httpClient.execute(httpPost);
                    int statusCode = response.getStatusLine().getStatusCode();
                    final String responseBody = EntityUtils.toString(response.getEntity());
                    Log.i(TAG, "Signed in as: " + responseBody);
                } catch (ClientProtocolException e) {
                    Log.e(TAG, "Error sending ID token to backend.", e);
                } catch (IOException e) {
                    Log.e(TAG, "Error sending ID token to backend.", e);
                }
            } else {
                // There was some error getting the ID Token
                // ...
                Toast.makeText(getApplicationContext(), R.string.dialog_error_login_text, Toast.LENGTH_LONG).show();
            }
        }

    }

当我尝试从中获取代码时

code = GoogleAuthUtil.getToken(getApplicationContext(), account, scopes);

我的作用域在哪里

String scope = "oauth2:server:client_id:" + CLIENT_ID + ":api_scope:" + sc;

其中 sc = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.login";

CLIENT_ID 是我在开发者控制台中生成的 Web 服务器客户端 ID。

我来了

10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity: com.google.android.gms.auth.GoogleAuthException: Unknown
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at com.google.android.gms.auth.GoogleAuthUtil.zza(Unknown Source)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at com.example.login.LoginActivity$GetIdTokenTask.doInBackground(LoginActivity.java:202)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at com.example.login.LoginActivity$GetIdTokenTask.doInBackground(LoginActivity.java:179)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
10-19 06:54:39.535 26012-26510/com.example.login E/LoginActivity:     at java.lang.Thread.run(Thread.java:818)

我不知道为什么会出现此错误。我尝试更改范围,但是当我使用 CLIENT_ID 时,它给了我这个错误。

如果我使用 Scope 如下:

String scope = "oauth2:https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.login";

它给了我权限错误:

com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission

我不知道我的代码有什么问题。非常感谢任何帮助。卡了快 2 天了。

【问题讨论】:

    标签: android oauth-2.0 google-oauth google-signin


    【解决方案1】:

    在您的 onConnectionFailed 中,您必须添加以下内容:

    private static final int REQUEST_CONSENT = 2;
             @Override
                    public void onConnectionFailed(ConnectionResult connectionResult) {
                        // Could not connect to Google Play Services.  The user needs to select an account,
                        // grant permissions or resolve an error in order to sign in. Refer to the javadoc for
                        // ConnectionResult to see possible error codes.
                        Log.d(TAG, "onConnectionFailed:" + connectionResult);
    
                        if (!mIsResolving && mShouldResolve) {
             if(!connectionResult.hasResolution()){
                            if (mGoogleApiClient.isUserResolvableError(connectionResult.getErrorCode())){
                                  Dialog dialog = mGoogleApiClient.getErrorDialog(activityContext, connectionResult.getErrorCode(), REQUEST_CONSENT);
                                 dialog.show();               
                                 return;
                            }
    
                        }
                            if (connectionResult.hasResolution()) {
                                try {
                                    connectionResult.startResolutionForResult(this, RC_SIGN_IN);
                                    mIsResolving = true;
                                } catch (IntentSender.SendIntentException e) {
                                    Log.e(TAG, "Could not resolve ConnectionResult.", e);
                                    mIsResolving = false;
                                    mGoogleApiClient.connect();
                                }
                            }
                        }
                    }
    

    将向用户显示一个对话框同意,在接受后应解决 UserRecoverableException。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-31
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      • 2021-11-04
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多