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

Google OAuth有限输入设备应用报错:unsupported_grant_type

问题排查与修复

你的错误根源在于请求token接口时的参数传递方式与设置的Content-Type不匹配:

你明确设置了Content-Type: application/x-www-form-urlencoded,但却用json参数传递数据——requests会自动将json参数的内容序列化为JSON格式,甚至会覆盖你手动设置的Content-Type,导致后端无法正确解析grant_type参数,最终返回"unsupported_grant_type"错误。

另外,grant_type无需手动做URL编码,直接使用原始字符串即可。

修复后的代码如下:

import json
import requests
import time

def main():
    with open("client_secret.json") as f:
        creds = json.load(f)  # 简化读取逻辑,无需先read再loads

    # 获取设备码
    device_code_res = requests.post(
        "https://oauth2.googleapis.com/device/code",
        json={
            "client_id": creds['installed']['client_id'],
            "scope": "https://www.googleapis.com/auth/youtube"
        }
    )
    if not device_code_res.ok:
        print("获取设备码失败:", device_code_res.text)
        return
    reply = device_code_res.json()
    
    # 提示用户完成验证(这一步不能省略,否则直接请求token会返回授权未完成)
    print(f"请访问 {reply['verification_url']},输入代码 {reply['user_code']} 完成验证")
    
    # 轮询请求token,等待用户完成验证
    interval = reply.get('interval', 5)
    while True:
        token_res = requests.post(
            "https://oauth2.googleapis.com/token",
            headers={"Content-Type": "application/x-www-form-urlencoded"},
            data={  # 改用data参数传递表单格式数据
                "client_id": creds['installed']['client_id'],
                "device_code": reply['device_code'],
                "grant_type": "urn:ietf:params:oauth:grant-type:device_code"
            }
        )
        token_data = token_res.json()
        if token_res.ok:
            print("获取token成功:", token_data)
            break
        # 处理常见的等待状态
        if token_data.get("error") == "authorization_pending":
            time.sleep(interval)
            interval = min(interval * 2, 60)  # 避免轮询过于频繁
        else:
            print("获取token失败:", token_data)
            break

if __name__ == "__main__":
    main()

额外补充:

  • 设备授权流程必须等待用户完成验证后才能获取到有效token,原代码直接在获取设备码后立即请求token,大概率会返回"authorization_pending"错误,因此添加了轮询逻辑,并根据返回的interval控制轮询间隔。
  • 简化了客户端凭证的读取方式,json.load(f)可以直接读取文件中的JSON内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 19:44:55