获取TokenResponseException:401未经授权

时间:2017-04-09 21:22:13

标签: java google-api oauth-2.0 gmail-api google-oauth2

我在google https://developers.google.com/identity/sign-in/web/server-side-flow中使用了以下示例,到目前为止我能够实现以下步骤:

  1. 用户在客户端(浏览器)进行身份验证
  2. 返回代码并保存在服务器db
  3. 在要求授权代码时TokenResponseException:401 Unauthorized。
  4. 我检查了以下内容:

    1. API已启用
    2. over https://developers.google.com/oauthplayground我使用相同的客户端ID和客户端密码测试了访问权限并且可以正常运行
    3. 阅读几乎所有与此问题相关的SO查询,但没有一个真正有用。
    4. 尝试撤消所有用户权限,并要求他们获取新代码。
    5. 以下是我正在使用的代码:

      public void getUserAuthTokens(String authCode){
          try {
      
              GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(
                      JacksonFactory.getDefaultInstance(),new FileReader(new ClassPathResource("static\\client_secret.json").getFile()));
      
              List<String> scopes = new ArrayList<>();
              scopes.add("https://www.googleapis.com/auth/gmail.readonly");
              //String scopes[]={"https://www.googleapis.com/auth/gmail.readonly"};
      
              Collection<String> SCOPES
                      = Collections.unmodifiableCollection(
                      Arrays.asList(
                              new String[]{
                                      GmailScopes.GMAIL_READONLY
                              }));
              GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(new NetHttpTransport(),JacksonFactory.getDefaultInstance(),
                      "https://www.googleapis.com/oauth2/v4/token",
                      clientSecrets.getDetails().getClientId(),
                      clientSecrets.getDetails().getClientSecret(),
                      authCode).setRedirectUri(clientSecrets.getDetails().getRedirectUris().get(0)).setScopes(SCOPES).execute();
      
      
              String accessToken = tokenResponse.getAccessToken();
              System.out.print("Token is: "+accessToken);
          }catch (IOException x){
              x.printStackTrace();
      
          }
      
      }
      

      作为旁注,如果我没有使用setRedirectUri(clientSecrets.getDetails()。getRedirectUris()。get(0))那么我得到“重定向不匹配错误”

      当我用完时,我会非常感谢有关这方面的任何想法

3 个答案:

答案 0 :(得分:0)

根据Google API返回的Standard Error Responses,错误代码401 Unauthorized表示为请求提供的授权凭据存在问题。您可能想要检查以下可能的原因:

  • OAuth访问令牌已过期,需要刷新。这可以通过提前刷新访问令牌来避免,但代码也可以捕获此错误,刷新令牌并自动重试。
  • 提供了多个不匹配的授权;只选择一种模式。
  • OAuth访问令牌的绑定项目与提供的开发人员密钥相关联的项目不匹配。
  • Authorization标头格式无法识别或使用不受支持的凭据类型。

有关使用OAuth 2.0访问Google API的详情,请参阅此documentation。此相关SO post中的建议解决方案也可能有所帮助。

答案 1 :(得分:0)

经过大量的调试和搜索,我找到了一个有效的解决方案,我在这里发帖,以防有人遇到同样的问题。

以下是我使用的代码:

GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(new NetHttpTransport(),JacksonFactory.getDefaultInstance(),
                "https://www.googleapis.com/oauth2/v4/token",
                clientSecrets.getDetails().getClientId(),
                clientSecrets.getDetails().getClientSecret(),
                authCode, "postmessage")
                .execute();

您可以阅读有关postmessage @ Google+ Sign-in for server-side apps, exchanging auth code for access token

的更多信息

希望有所帮助。

答案 2 :(得分:0)

我最终发现由于我的数据存储没有使用不同的范围更新其凭据,我看到“TokenResponseException:401 Unauthorized”。像魔术一样,在从头开始重新启动测试授权之前删除数据存储(并清除会话缓存)会导致成功。我不建议针对每种情况采取这些措施;但是,当所有其他方法都失败时,它们可能值得尝试作为调试步骤。