如何使用 gmail api 获取访问令牌 [英] How to get access token using gmail api

查看:49
本文介绍了如何使用 gmail api 获取访问令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我根据本文档获得了授权代码.但是当我尝试获取访问令牌时,我总是遇到错误.有人可以帮我吗?

public String AccessToken(){String accessToken = "";StringBuilder strBuild = new StringBuilder();String authURL = "https://accounts.google.com/o/oauth2/token?";字符串代码 = "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());尝试{URL obj = 新 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(例外e){System.out.println("错误.");}返回 "";}

当我运行这段代码时,输​​出是:<代码>400错误请求

解决方案

如何使用 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 API

您必须访问 Google Developers Console 以获取 OAuth 2.0 凭据,例如 Google 和您的应用程序都知道的客户端 ID客户端密钥

<小时>

根本原因分析:

问题 1:

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

问题 2:

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

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

<块引用>

错误.

解决方案:

我知道您的代码与此类似 教程

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

private String getAccessToken(){尝试{映射<字符串,对象>params = new LinkedHashMap<>();params.put("grant_type","re​​fresh_token");params.put("client_id",[您的客户 ID]);params.put("client_secret",[您的客户秘密]);params.put("refresh_token",[你的刷新令牌]);StringBuilder postData = new StringBuilder();for(Map.Entry 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 = 新 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 缓冲区 = new StringBuffer();for (String line = reader.readLine(); line != null; line = reader.readLine()){缓冲区.追加(行);}JSONObject json = new JSONObject(buffer.toString());String accessToken = json.getString("access_token");返回访问令牌;}捕获(异常前){ex.printStackTrace();}返回空;}

<块引用>

对于访问google play android developer api,您需要通过先前刷新令牌以获取访问令牌

private String getAccessToken(String refreshToken){HttpClient 客户端 = 新的 DefaultHttpClient();HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");尝试{列表nameValuePairs = new ArrayList(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 缓冲区 = new StringBuffer();for (String line = reader.readLine(); line != null; line = reader.readLine()){缓冲区.追加(行);}JSONObject json = new JSONObject(buffer.toString());String accessToken = json.getString("access_token");返回访问令牌;}catch (IOException e) { e.printStackTrace();}返回空;}

资源链接:

希望这个 samplesresource link 将帮助您解决您的问题并获得访问令牌的访问权.

<小时>

什么是 400 错误请求?H2>

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

推荐的操作:您需要对 API 查询进行更改才能使其正常工作.

<块引用>

对于HTTP/1.1 400 Bad Request error,您可以通过我的另一个回答.这将帮助您了解您的主机需要使用以及需要应用哪些条件.

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

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

  1. 用户已撤销访问权限.
  2. 令牌已六个月未使用.
  3. 用户更改了密码,令牌包含 Gmail、日历、联系人或环聊范围.
  4. 用户帐户超过了一定数量的令牌请求.

目前每个客户端每个用户帐户的刷新令牌限制为 25 个.如果达到限制,创建新令牌会自动使最旧的令牌无效,而不会发出警告.此限制不适用于服务帐号.

应采取哪些预防措施?

注意事项 - 1:

<块引用>

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

如果用户授予权限,谷歌授权服务器向您的应用程序发送访问令牌(或授权代码您的应用程序可用于获取访问令牌).如果用户这样做不授予权限,服务器返回错误.

注意事项 - 2:

<块引用>

如果为 Google+ API 颁发了访问令牌,则不会授予访问 Google 通讯录 API.但是,您可以发送该访问多次向 Google+ API 发送令牌以进行类似操作.

注意事项 - 3:

<块引用>

访问令牌的有效期通常为 1 小时,之后如果你尝试使用它,你会得到一个错误.Google 凭据负责自动刷新"令牌,这只是意味着获取新的访问令牌.

将刷新令牌保存在安全的长期存储中并继续使用只要它们仍然有效.限制适用于每个客户端 - 用户组合和每个用户跨所有客户端,这些限制是不同的.如果你的应用程序请求足够的刷新令牌来检查其中一个限制,旧的刷新令牌停止工作.

I got the authorization code following this document. But when I tried to get access token, I always got errors. Can anyone help me ?

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 "";
}

when I ran this code, the output is: 400 Bad Request

解决方案

How to get access token using gmail api?

Ans: As per your following tutorial, you are using OAuth 2.0. So there is a basic pattern for accessing a Google API using OAuth 2.0. It follows 4 steps:

  1. Obtain OAuth 2.0 credentials from the Google Developers Console.
  2. Obtain an access token from the Google Authorization Server.
  3. Send the access token to an API.
  4. Refresh the access token, if necessary.

For details, you can follow the tutorial - Using OAuth 2.0 to Access Google APIs

You have to visit the Google Developers Console to obtain OAuth 2.0 credentials such as a client ID and client secret that are known to both Google and your application


Root Cause Analysis:

Issue-1:

After studying your code, some lacking are found. If your code runs smoothly, then the code always give an empty string. Because your AccessToken() method always return return "";

Issue-2:

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

Your try catch block is going exception block. Because, it seems that you have not completed your code properly. You have missed encoding as well as using JSONObject which prepares the access token. So it is giving output as

Error.

Solution:

I got that your code is similar with this tutorial

As your code needs more changes to solve your issue. So I offer you to use LinkedHashMap or ArrayList. Those will provide easier way to make solution. So I give you 2 sample code to make your life easier. You can choose any of them. You need to change refresh_token, client id, client secret and grant type as yours.

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;
}

For accessing google play android developer api, you need to pass the previous refresh token to get 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;
}

Resource Link:

Hope that, this samples and resource link will help you to solve your issue and get access of access token.


What is 400 bad request?

Ans: It indicates that the query was invalid. Parent ID was missing or the combination of dimensions or metrics requested was not valid.

Recommended Action: You need to make changes to the API query in order for it to work.

For HTTP/1.1 400 Bad Request error, you can go through my another answer. It will help you to make sense about which host you need to use and which conditions you need to apply.

Why token expires? What is the limit of token?

A token might stop working for one of these reasons:

  1. The user has revoked access.
  2. The token has not been used for six months.
  3. The user changed passwords and the token contains Gmail, Calendar, Contacts, or Hangouts scopes.
  4. The user account has exceeded a certain number of token requests.

There is currently a limit of 25 refresh tokens per user account per client. If the limit is reached, creating a new token automatically invalidates the oldest token without warning. This limit does not apply to service accounts.

Which precautions should be followed?

Precautions - 1:

Some requests require an authentication step where the user logs in with their Google account. After logging in, the user is asked whether they are willing to grant the permissions that your application is requesting. This process is called user consent.

If the user grants the permission, the Google Authorization Server sends your application an access token (or an authorization code that your application can use to obtain an access token). If the user does not grant the permission, the server returns an error.

Precautions - 2:

If an access token is issued for the Google+ API, it does not grant access to the Google Contacts API. You can, however, send that access token to the Google+ API multiple times for similar operations.

Precautions - 3:

An access token typically has an expiration date of 1 hour, after which you will get an error if you try to use it. Google Credential takes care of automatically "refreshing" the token, which simply means getting a new access token.

Save refresh tokens in secure long-term storage and continue to use them as long as they remain valid. Limits apply to the number of refresh tokens that are issued per client-user combination, and per user across all clients, and these limits are different. If your application requests enough refresh tokens to go over one of the limits, older refresh tokens stop working.

这篇关于如何使用 gmail api 获取访问令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆