Android GoogleCredential无效凭据

时间:2016-04-13 12:34:05

标签: android credentials google-drive-android-api

我有一个从服务器收到的Google云端硬盘访问令牌。收到后,我尝试使用此令牌初始化GoogleCredential,然后对Drive API执行请求。但是当我尝试执行请求时,我会抓住下一个堆栈跟踪:

04-13 15:23:22.715 29184-29570/com.rcd.perfecto W/System.err: com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
04-13 15:23:22.715 29184-29570/com.rcd.perfecto W/System.err: {
04-13 15:23:22.715 29184-29570/com.rcd.perfecto W/System.err:   "code" : 401,
04-13 15:23:22.715 29184-29570/com.rcd.perfecto W/System.err:   "errors" : [ {
04-13 15:23:22.715 29184-29570/com.rcd.perfecto W/System.err:     "domain" : "global",
04-13 15:23:22.715 29184-29570/com.rcd.perfecto W/System.err:     "location" : "Authorization",
04-13 15:23:22.715 29184-29570/com.rcd.perfecto W/System.err:     "locationType" : "header",
04-13 15:23:22.715 29184-29570/com.rcd.perfecto W/System.err:     "message" : "Invalid Credentials",
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     "reason" : "authError"
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:   } ],
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:   "message" : "Invalid Credentials"
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err: }
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1056)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.utils.storages.helpers.GoogleDriveHelper.getQuotaInfo(GoogleDriveHelper.java:163)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.utils.storages.helpers.GoogleDriveHelper.addCloud(GoogleDriveHelper.java:100)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.utils.storages.helpers.GoogleDriveHelper.initClient(GoogleDriveHelper.java:93)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.utils.storages.helpers.GoogleDriveHelper.<init>(GoogleDriveHelper.java:53)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.utils.storages.helpers.GoogleDriveHelper.getInstance(GoogleDriveHelper.java:107)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.utils.storages.helpers.StoragesHelper.getGoogleDriveHelper(StoragesHelper.java:135)
04-13 15:23:22.716 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.utils.storages.helpers.StoragesHelper.initClients(StoragesHelper.java:97)
04-13 15:23:22.717 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.utils.CloudStorageCollector.saveCloudsToDatabase(CloudStorageCollector.java:61)
04-13 15:23:22.717 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.services.SyncApiService.getOldCloudsSync(SyncApiService.java:205)
04-13 15:23:22.717 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.services.SyncApiService.startCloudSync(SyncApiService.java:194)
04-13 15:23:22.717 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.services.SyncApiService.handleActionFullSync(SyncApiService.java:176)
04-13 15:23:22.717 29184-29570/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.services.SyncApiService.onHandleIntent(SyncApiService.java:153)
04-13 15:23:22.717 29184-29570/com.rcd.perfecto W/System.err:     at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
04-13 15:23:22.717 29184-29570/com.rcd.perfecto W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
04-13 15:23:22.718 29184-29570/com.rcd.perfecto W/System.err:     at android.os.Looper.loop(Looper.java:148)
04-13 15:23:22.718 29184-29570/com.rcd.perfecto W/System.err:     at android.os.HandlerThread.run(HandlerThread.java:61)

我如何初始化凭据并向云端硬盘执行请求:

private void initClient() {
    JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
    HttpTransport transport = AndroidHttp.newCompatibleTransport();
    try {
        GoogleClientSecrets googleClientSecrets = loadClientSecretsResource(mContext, jsonFactory);
        GoogleCredential credential = new GoogleCredential.Builder()
                .setClientSecrets(googleClientSecrets)
                .setJsonFactory(jsonFactory)
                .setTransport(transport)
                .build();
        credential.setAccessToken(AppPreferences.Storage.GoogleDrive.getToken(mContext));
        credential.refreshToken();
        mService = new Drive.Builder(transport, jsonFactory, credential)
                .setApplicationName(mContext.getResources().getString(R.string.app_name))
                .build();
        addCloud();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void addCloud() {
    Map<String, Long> quotaInfo = getQuotaInfo();
    CloudStorageCollector.saveCloudToDatabase(AppPreferences.Storage.GoogleDrive.getToken(mContext), BaseVault.VaultCode.GoogleDriveVault,
            quotaInfo.get(StoragesHelper.USED_QUOTA_KEY), quotaInfo.get(StoragesHelper.TOTAL_QUOTA_KEY));
}

public Map<String, Long> getQuotaInfo() {
    if (mService == null) return null;
    Map<String, Long> quotaInfo = new HashMap<>();
    try {
        About about = mService.about().get().execute();
        quotaInfo.put(StoragesHelper.USED_QUOTA_KEY, about.getQuotaBytesUsed());
        quotaInfo.put(StoragesHelper.TOTAL_QUOTA_KEY, about.getQuotaBytesTotal());
        return quotaInfo;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

getQuotaInfo方法中,我捕获了异常。我做错了什么?

1 个答案:

答案 0 :(得分:0)

错误401: Invalid Credentials或无效的授权标头意味着您使用的访问令牌已过期或无效。

因此,尝试使用长期刷新令牌刷新访问令牌。如果失败,请尝试再次检查authorizing requests。以下是步骤:

  1. 创建应用程序时,请使用 Google Developers Console 进行注册。然后,Google会提供您稍后需要的信息,例如客户端ID和客户端密码。

  2. 在Google Developers Console中激活Drive API。 (如果未在开发人员控制台中列出API,则跳过此步骤。)

  3. 当您的应用需要访问用户数据时,它会要求Google提供特定范围的访问权限。

  4. Google向用户显示同意屏幕,要求他们授权您的应用程序请求他们的部分数据。

  5. 如果用户批准,那么Google会为您的应用提供一个短期访问令牌。

  6. 您的应用程序请求用户数据,将访问令牌附加到请求中。

  7. 如果Google确定您的请求和令牌有效,则会返回请求的数据。

  8. 某些流程包含其他步骤,例如使用刷新令牌来获取新的访问令牌。有关各种类型应用程序的流的详细信息,请参阅Google's OAuth 2.0 documentation