我正在尝试通过Google联系人API验证我的应用程序。我已经走过Oauth2流程的第一步,并且拥有授权码。我正在尝试将此代码交换为访问 token 和刷新 token ,但是当我尝试从googleapis.com/oauth2/v4/token获取 token 时,

响应:“invalid_grant”“错误请求”错误400。

我的代码

try
        {
            Map<String,Object> params = new LinkedHashMap<>();
            params.put("grant_type","authorization_code");
            params.put("code", authCode);
            params.put("client_id",CLIENTE_ID);
            params.put("client_secret",CLIENTE_ID_SECRETO);
            params.put("redirect_uri","http://localhost:8080/conob/api2/contatos/insert");

            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://www.googleapis.com/oauth2/v4/token");
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setUseCaches(false);
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            con.setRequestProperty("charset", "utf-8");
            con.setRequestProperty("Content-Length", postData.toString().length() + "");
            con.getOutputStream().write(postDataBytes);


            BufferedReader reader = null;
            try {
                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 e) {
                reader = new BufferedReader(new InputStreamReader(con.getErrorStream()));

                StringBuffer buffer = new StringBuffer();

                for (String line = reader.readLine(); line != null; line = reader.readLine()){
                    buffer.append(line);
                }

                System.out.println(buffer.toString());
                System.out.println(e.toString());
            }

        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return null;

参数输出:

grant_type = authorization_code&code = AUTHORIZATION_CODE&client_id = CLIENTE_ID&client_secret = CLIENTE_SECRET&redirect_uri = http%3A%2F%2Flocalhost%3A8080%2Fconob%2Fapi2%2Fcontatos%2Finsert

我在许多论坛中搜索了许多小时,但没有为我的问题得出解决方案。

基本上,我的应用需要在公司Intranet的Google帐户上插入新联系人。

我的问题是响应是“invalid_grant”吗?

好的代码,从现在开始谢谢。

最佳答案

OAuth2规范中,对于所有与无效/过期/吊销的 token (身份验证授权或刷新 token )相关的错误响应,"invalid_grant"都是一种包罗万象的东西。

常见原因

  • 用户已积极撤消对我们应用程序
  • 的访问
  • 用户已重置/恢复了他们的Google密码
    2015年12月,Google更改了默认行为,以便为非Google Apps用户重置密码会自动撤消所有用户的应用刷新 token 。对于所有的api联系人来说,这不是事实之一,但我想我还是会注意的。

  • 除此之外,还有许多其他可能导致错误的潜在原因:
  • 服务器时钟/时间不同步
  • 无权进行离线访问
  • 由Google节制
  • 使用过期的刷新 token
  • 使用过期的授权码。
  • 用户已停用6个月了
  • 刷新 token
  • 不正确或无效
  • 使用服务人员电子邮件代替客户端ID
  • 短时间内访问 token 太多
  • 客户端SDK可能已过时

  • 端点

    我意识到发现文档说googleapis.com/oauth2/v4/token,但是出于某种原因,此端点并不总是有效,请尝试使用accounts.google.com/o/oauth2/token
    redirect_uri_mismatch

    意味着您随请求http://localhost:8080/conob/api2/contatos/insert发送的重定向uri不是您在Google开发者控制台中添加的重定向uri之一。您需要返回到Google Developer Console并添加此重定向uri。

    请注意,您可能要考虑使用google people api,它比以前的google contacts api更容易使用。

    10-07 19:04
    查看更多