如何使用 gmail api 获取访问令牌

新手上路,请多包涵

我按照 这份文件 获得了授权码。但是当我试图获取访问令牌时,我总是会出错。谁能帮我 ?

 public String AccessToken()
{
    String accessToken = "";
    StringBuilder strBuild = new StringBuilder();

    String authURL = "https://accounts.google.com/o/oauth2/token?";
    String code = "4/SVisuz_x*********************";
    String client_id = "******************e.apps.googleusercontent.com";
    String client_secret = "*******************";
    String redirect_uri = "urn:ietf:wg:oauth:2.0:oob";
    String grant_type="authorization_code";
    strBuild.append("code=").append(code)
            .append("&client_id=").append(client_id)
            .append("&client_secret=").append(client_secret)
            .append("&redirect_uri=").append(redirect_uri)
            .append("&grant_type=").append(grant_type);
    System.out.println(strBuild.toString());
    try{
        URL obj = new URL(authURL);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setDoOutput(true);
        con.setRequestMethod("POST");

        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        con.setRequestProperty("Host", "www.googleapis.com");

        //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(con.getOutputStream()));
        //bw.write(strBuild.toString());
        //bw.close();

        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(strBuild.toString());
        wr.flush();
        wr.close();

        //OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
        System.out.println(con.getResponseCode());
        System.out.println(con.getResponseMessage());

    } catch (Exception e)
    {
        System.out.println("Error.");
    }
    return "";
}

当我运行这段代码时,输出是: 400 Bad Request

原文由 tqjustc 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 492
1 个回答

如何使用 gmail api 获取访问令牌?

答: 根据 您的以下教程,您正在使用 OAuth 2.0 。因此,有一个使用 OAuth 2.0 访问 Google API 的基本模式。它遵循 4 个步骤:

  1. 从 Google Developers Console 获取 OAuth 2.0 凭据。
  2. 从 Google 授权服务器获取访问令牌。
  3. 将访问令牌发送到 API。
  4. 如有必要,刷新访问令牌。

具体可以参考教程- 使用OAuth 2.0访问Google APIs

您必须访问 Google Developers Console 以获得 OAuth 2.0 凭据,例如 Google 和您的应用程序都知道的 client IDclient secret


根本原因分析:

问题 1:

研究你的代码后,发现了一些不足。如果你的代码运行顺利,那么代码总是给出一个空字符串。因为你的 AccessToken() 方法总是返回 return "";

问题 2:

  catch (Exception e)
    {
        System.out.println("Error.");
    }

您的 try catch 块将成为异常块。因为,您似乎没有正确完成代码。您错过了 encoding 以及使用准备访问令牌的 JSONObject 。所以它给出的输出是

错误。

解决方案:

我知道您的代码与本 教程 相似

由于您的代码需要更多更改才能解决您的问题。所以我建议您使用 LinkedHashMapArrayList 。这些将提供更简单的解决方案。所以我给你 2 个示例代码,让你的生活更轻松。您可以选择其中任何一个。您需要将 refresh_token, client id, client secret and grant type 更改为您的。

 private String getAccessToken()
{
    try
    {
        Map<String,Object> params = new LinkedHashMap<>();
        params.put("grant_type","refresh_token");
        params.put("client_id",[YOUR CLIENT ID]);
        params.put("client_secret",[YOUR CLIENT SECRET]);
        params.put("refresh_token",[YOUR REFRESH TOKEN]);

        StringBuilder postData = new StringBuilder();
        for(Map.Entry<String,Object> param : params.entrySet())
        {
            if(postData.length() != 0)
            {
                postData.append('&');
            }
            postData.append(URLEncoder.encode(param.getKey(),"UTF-8"));
            postData.append('=');
            postData.append(URLEncoder.encode(String.valueOf(param.getValue()),"UTF-8"));
        }
        byte[] postDataBytes = postData.toString().getBytes("UTF-8");

        URL url = new URL("https://accounts.google.com/o/oauth2/token");
        HttpURLConnection con = (HttpURLConnection)url.openConnection();
        con.setDoOutput(true);
        con.setUseCaches(false);
        con.setRequestMethod("POST");
        con.getOutputStream().write(postDataBytes);

        BufferedReader  reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
        StringBuffer buffer = new StringBuffer();
        for (String line = reader.readLine(); line != null; line = reader.readLine())
        {
            buffer.append(line);
        }

        JSONObject json = new JSONObject(buffer.toString());
        String accessToken = json.getString("access_token");
        return accessToken;
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
    return null;
}

访问google play android developer api ,需要通过之前的refresh token获取access token

 private String getAccessToken(String refreshToken){

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
try
{
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
    nameValuePairs.add(new BasicNameValuePair("grant_type",    "refresh_token"));
    nameValuePairs.add(new BasicNameValuePair("client_id",     GOOGLE_CLIENT_ID));
    nameValuePairs.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENT_SECRET));
    nameValuePairs.add(new BasicNameValuePair("refresh_token", refreshToken));
    post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    org.apache.http.HttpResponse response = client.execute(post);
    BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    StringBuffer buffer = new StringBuffer();
    for (String line = reader.readLine(); line != null; line = reader.readLine())
    {
        buffer.append(line);
    }

    JSONObject json = new JSONObject(buffer.toString());
    String accessToken = json.getString("access_token");

    return accessToken;

}
catch (IOException e) { e.printStackTrace(); }

return null;
}

资源链接:

希望这个 samplesresource link 将帮助您解决问题并获得 access token 的访问权限。


什么是400错误请求?

Ans: 表示查询无效。父 ID 缺失或请求的维度或指标组合无效。

建议的操作: 您需要更改 API 查询才能使其正常工作。

对于 HTTP/1.1 400 Bad Request error ,你可以看看 我的另一个答案它将帮助您理解 which host you** **need to use 以及您需要申请哪些条件

为什么令牌会过期?令牌的限制是多少?

由于以下原因之一,令牌可能会停止工作:

  1. 用户具有 revoked 访问权限。
  2. 该令牌尚未用于 six months
  3. user changed passwords 和令牌包含 Gmail、日历、联系人或环聊范围。
  4. 用户帐户有 exceeded a certain number of token requests

currently a limit of 25 refresh tokens per user account per client 。如果达到限制,创建新令牌会自动使最旧的令牌失效,而不会发出警告。此限制不适用于服务帐户。

应遵循哪些预防措施?

注意事项 - 1:

某些请求需要用户使用其 Google 帐户登录的身份验证步骤。登录后,系统会询问用户是否愿意授予您的应用程序请求的权限。此过程称为用户同意。

如果用户授予权限,Google 授权服务器会向您的应用程序发送访问令牌(或您的应用程序可用于获取访问令牌的授权代码)。如果用户不授予权限,服务器将返回一个错误。

注意事项 - 2:

如果为 Google+ API 颁发了访问令牌,它不会授予对 Google Contacts API 的访问权限。但是,您可以多次将该访问令牌发送到 Google+ API 以进行类似操作。

注意事项 - 3:

访问令牌通常有 1 小时的到期日期,如果您尝试使用它,将在 1 小时之后收到错误消息。 Google Credential 负责自动“刷新”令牌,这仅意味着获取新的访问令牌。

将刷新令牌保存在安全的长期存储中,并在它们仍然有效时继续使用它们。限制适用于每个客户端-用户组合以及所有客户端的每个用户颁发的刷新令牌的数量,并且这些限制是不同的。如果您的应用程序请求足够的刷新令牌以超过其中一个限制,则较旧的刷新令牌将停止工作。

原文由 SkyWalker 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题