【问题标题】:Google Drive invalid credentialsGoogle 云端硬盘凭据无效
【发布时间】:2013-09-07 02:09:27
【问题描述】:

我正在使用 GAE for java 并尝试使用 api 从谷歌驱动器读取文件。我使用了 DrEdit 的标准实现。我有一个 servlet,它使用我的帐户进行身份验证并使用以下 sn-p 存储凭据:

 protected void handleCallbackIfRequired(HttpServletRequest req,
      HttpServletResponse resp) throws IOException {
    String code = req.getParameter("code");
System.out.println("Code:" + code);

if (code != null) {
  // retrieve new credentials with code
  Credential credential = credentialManager.retrieve(code);

credentialManager.save(id, credential);
System.out.println("access token:" + credential.getAccessToken());
System.out.println("refresh token:" + credential.getRefreshToken());
  resp.sendRedirect("/");
}

}

  public Credential retrieve(String code) {
    System.out.println("Passed code to retrieve is:" + code);
      try {
      GoogleTokenResponse response = new GoogleAuthorizationCodeTokenRequest(
          transport,
          jsonFactory,
          clientSecrets.getWeb().getClientId(),
          clientSecrets.getWeb().getClientSecret(),
          code,
          clientSecrets.getWeb().getRedirectUris().get(0)).execute();

      Credential cred = buildEmpty();
      cred.setRefreshToken(response.getRefreshToken());
      cred.setAccessToken(response.getAccessToken());
      return cred;

    } catch (IOException e) {
      new RuntimeException("An unknown problem occured while retrieving token");
    }
    return null;
  }
}

accessToken 和 refreshToken 保存代码:

protected void handleCallbackIfRequired(HttpServletRequest req,
      HttpServletResponse resp) throws IOException {
    String code = req.getParameter("code");
    System.out.println("Code:" + code);

    if (code != null) {
      // retrieve new credentials with code
      Credential credential = credentialManager.retrieve(code);

    credentialManager.save(id, credential);
    System.out.println("access token:" + credential.getAccessToken());
    System.out.println("refresh token:" + credential.getRefreshToken());
      resp.sendRedirect("/");
    }
  }

在此之后,我希望 GAE 每次都会自动检索我的凭据并让我调用驱动器 API。但是,我在日志中看到以下消息。所以,我不确定为什么会这样。请注意,我创建的授权 url 包括离线范围。

  "code" : 401,
    "errors" : [ {
    "domain" : "global",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Invalid Credentials",
    "reason" : "authError"
    } ],
    "message" : "Invalid Credentials"
    }

强制重新认证后的日志:

2013-09-08 22:51:28.512
[s~sakshumweb-hrd/3.370083570818804963].<stdout>: Code:4/jYpKc6Mit2_0OTgR7dhpve0YGQCG.UoLMhsf6Fd4SEnp6UAPFm0GoUpACggI

I 2013-09-08 22:51:28.512
[s~sakshumweb-hrd/3.370083570818804963].<stdout>: Passed code to retrieve is:4/jYpKc6Mit2_0OTgR7dhpve0YGQCG.UoLMhsf6Fd4SEnp6UAPFm0GoUpACggI

I 2013-09-08 22:51:29.423
[s~sakshumweb-hrd/3.370083570818804963].<stdout>: access token:ya29.AHES6ZS3x8fPpq5G9YHmIvFHE098izZ0zyn7BCnZRDhYf3zdA-qNDtw

I 2013-09-08 22:51:29.424
[s~sakshumweb-hrd/3.370083570818804963].<stdout>: refresh token:null

I 2013-09-08 22:51:29.450
[s~sakshumweb-hrd/3.370083570818804963].<stdout>: authorization url:https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=auto&client_id=955443778501.apps.googleusercontent.com&redirect_uri=http://www.sakshum.org/GoogleOauth&response_type=code&scope=https://www.googleapis.com/auth/drive.readonly%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile

【问题讨论】:

  • 401 表示访问令牌无效。您应该检查您的代码以查看您是否正确获取并在必要时刷新访问令牌。
  • 谢谢!对我来说,刷新令牌一直为空。我正在使用的代码在上面添加。
  • 刷新令牌只提供一次。随后它将为空。您可能需要“强制”重新授权。
  • 我只是强制并且仍然看到 refreshToken 为空。我将登录添加到原始问题中
  • 该日志显示批准提示=自动。尝试将其设置为强制

标签: google-app-engine google-drive-api


【解决方案1】:

“没有过期并使用相同的accessToken”????真的吗?你读过https://developers.google.com/accounts/docs/OAuth2WebServer 吗?

【讨论】:

  • 对不起,我已经阅读了它,它说它将使用 refreshToken 生成 accessToken。我找不到可以做到这一点的代码。你能具体指出我在 google app engine for java 上处理它的代码吗?
  • 我不能指出你的代码在哪里。这个问题的答案中有一个例子stackoverflow.com/questions/18585279/…
【解决方案2】:

如果您启用了 Google 两阶段验证,那么无论您的 Google 密码是什么,都不会被接受。您需要(在 Google 上)生成所谓的应用程序特定密码 (ASP)。转到https://www.google.com/settings/account 并设置一个 ASP,输入您生成的密码作为代码中的密码,就完成了。

【讨论】:

    【解决方案3】:

    尝试在retrieve(String code)方法中替换,而不是:

    Credential cred = buildEmpty();
    cred.setRefreshToken(response.getRefreshToken());
    cred.setAccessToken(response.getAccessToken());
    return cred;
    

    替换为:

    Credential cred = buildEmpty();
    cred.setFromTokenResponse(response);
    return cred;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多