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

本地集成Google API获取access_token时遭遇400错误求助

Google OAuth2 获取Access Token时400错误排查

我尝试不依赖复杂SDK,直接通过API集成Google APIs。已成功获取Auth_code,但请求access_token时返回400 Bad Request错误:

400 Bad Request: "{ "error": "invalid_request", "error_description": "You cant sign in to this app because it doesnt comply with Google's OAuth 2.0 policy for keeping apps secure.You can let the app developer know that this app doesnt comply with one or more Google validation rules. "}"

我的应用是服务器端Web应用,域名后缀为.ngrok-free.app,且Redirect URI配置正确(已成功获取授权码)。相关Java代码如下:

public static void main(String[] args) {
    String url = "https://accounts.google.com/o/oauth2/v2/auth?" +
            "scope="+URLEncoder.encode("https://www.googleapis.com/auth/userinfo.email", StandardCharsets.UTF_8)+"&" +
            "access_type=offline&" +
            //"include_granted_scopes=true&" +
            "response_type=code&" +
            "state=dummy_val&" +
            "redirect_uri="+URLEncoder.encode("https://XXX/AIAutomation/oauth", StandardCharsets.UTF_8)+"" + "&" +
            "client_id="+ URLEncoder.encode(client_id, StandardCharsets.UTF_8);
    //String res = restTemplate.exchange(url, HttpMethod.GET, entity, String.class).getBody();
    System.out.println(url);
}

String url = "https://oauth2.googleapis.com/token?" +
                "code=" + URLEncoder.encode(authCode, StandardCharsets.UTF_8) +
                "&client_id=" + URLEncoder.encode(client_id, StandardCharsets.UTF_8) +
                "&client_secret=" + URLEncoder.encode(client_secret, StandardCharsets.UTF_8) +
                "&redirect_uri=" + URLEncoder.encode("https://XXX/AIAutomation/oauth", StandardCharsets.UTF_8) +
                "&grant_type=authorization_code";

        
RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
HttpEntity<String> entity = new HttpEntity<>("", headers);
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
obj = restTemplate.exchange(url, HttpMethod.POST, entity, Object.class).getBody();
            
result = obj.toString();

问题原因及解决方法

1. 核心问题:请求参数传递方式错误

Google OAuth2的token接口要求POST参数必须放在请求体中(表单格式),而不是拼接在URL上。你当前把所有参数都拼在URL里,同时请求体为空,违反了OAuth2安全规范,触发了Google的安全校验拦截。

2. 修复后的代码示例

修改token请求逻辑,将参数放入请求体:

// 构建表单参数
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", authCode);
params.add("client_id", client_id);
params.add("client_secret", client_secret);
params.add("redirect_uri", "https://XXX/AIAutomation/oauth");
params.add("grant_type", "authorization_code");

RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);

// URL仅保留基础地址,参数全部放在请求体
Object obj = restTemplate.exchange("https://oauth2.googleapis.com/token", HttpMethod.POST, entity, Object.class).getBody();
String result = obj.toString();

3. 额外检查点

  • 确认Google Cloud项目的OAuth consent screen状态:若处于测试状态,仅添加的测试用户可授权,非测试用户会触发安全错误,需发布到生产环境。
  • 核对redirect_uri:必须与Google Cloud控制台配置的完全一致(协议、域名、路径均大小写敏感)。
  • 移除手动编码:表单参数会自动处理URL编码,无需提前用URLEncoder.encode处理参数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:42:38