You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google OAuth2授权码兑换Token返回400错误排查求助

解决Google OAuth2授权码兑换Access Token的400错误(Java HttpClient实现)

核心问题:未读取错误响应体

你的代码当前只要响应码不是200就直接返回null,完全忽略了Google OAuth2接口返回的错误详情。400响应的响应体里会明确说明错误原因(比如redirect_uri不匹配、授权码过期、参数格式错误等),这是排查问题的关键。

第一步:修改代码读取错误响应

先修改代码,确保无论响应码是什么,都读取并打印响应内容:

private String getTokenJson(String code, boolean isProduction) {
    HttpPost post = new HttpPost("https://oauth2.googleapis.com/token");

    List<NameValuePair> pairs = new ArrayList<>();
    pairs.add(new BasicNameValuePair("code", code));
    pairs.add(new BasicNameValuePair("client_id", gmailSecretsService.getClientId()));
    pairs.add(new BasicNameValuePair("client_secret", gmailSecretsService.getClientSecret()));
    pairs.add(new BasicNameValuePair("grant_type", "authorization_code"));
    pairs.add(new BasicNameValuePair("redirect_uri", getRedirectUri(isProduction)));

    // 显式指定UTF-8编码,避免参数编码错误
    post.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8));

    try (CloseableHttpClient httpclient = HttpClientBuilder.create().build()) {
        try (CloseableHttpResponse response = httpclient.execute(post)) {
            int statusCode = response.getCode();
            String responseContent = "";
            
            // 读取所有响应内容,包括错误体
            if (response.getEntity() != null) {
                responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            }

            if (statusCode != 200) {
                LOGGER.error("Token兑换失败,状态码: {}, 错误详情: {}", statusCode, responseContent);
                return null;
            }

            LOGGER.info("Token兑换成功,响应: {}", responseContent);
            return responseContent;
        }
    } catch (IOException e) {
        LOGGER.error("请求Token接口异常", e);
        return null;
    }
}

第二步:根据错误信息排查问题

运行修改后的代码,查看日志里的错误详情,常见问题包括:

  • redirect_uri_mismatch:代码里的redirect_uri和Google控制台配置的不一致,检查协议(http/https)、端口、路径是否完全一致(包括末尾是否有斜杠)。
  • invalid_grant:授权码已过期或已被使用,重新获取授权码再尝试。
  • invalid_client:client_id或client_secret错误,检查是否和控制台的一致,注意不要有多余的空格或换行。

额外注意点

  1. 编码问题:原代码中UrlEncodedFormEntity未指定编码,默认可能不是UTF-8,而curl默认使用UTF-8,这会导致包含特殊字符的参数(比如client_secret)编码错误,显式指定StandardCharsets.UTF_8可以解决这个问题。
  2. 简化配置:暂时去掉自定义的BasicHttpClientConnectionManager和RequestConfig,用默认HttpClient配置,排除配置冲突导致的问题。

内容的提问来源于stack exchange,提问作者HeronAlgoSearch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:35:55