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

传入有效Token时google.oauth2.credentials.Credentials调用YouTube API失败排查

问题:用Google Python SDK调用YouTube API时,明明传了有效Access Token却还是报授权错误

我看了你遇到的情况:你已经用curl成功调用YouTube Channels API拿到了自己的频道数据,但换成Google官方的Python库实现时,却出现了和没传Access Token一样的authorizationRequired错误,而且你确认自己的Access Token和API Key都是有效的——这情况我之前也碰到过,问题出在Python客户端库的参数优先级上!

问题根源

当你在build方法里**同时传入credentials(带Access Token)和developerKey**时,Google的Python客户端库会优先使用developerKey发起请求,直接忽略掉credentials里的Access Token。这就导致你的请求根本没带上Authorization: Bearer xxx头,和你手动去掉curl里的Authorization头效果一样,自然触发了401授权错误。

解决办法

最简单的修复就是去掉build方法里的developerKey参数,因为当你使用OAuth2的Credentials(也就是你的Access Token)进行用户身份验证时,不需要再传入API Key——API Key主要用于不需要用户身份的公开数据请求,而mine=true的请求必须依赖用户授权的Access Token。

修改后的get_authenticated_service函数应该是这样:

def get_authenticated_service(options):
    creds = google.oauth2.credentials.Credentials(options.access_token)
    # 移除了developerKey参数
    return build('youtube', 'v3', credentials=creds)

补充:如果确实需要用到API Key的场景

如果之后你有需要同时结合API Key和OAuth授权的请求(比如某些特殊的混合权限接口),可以不在build里传developerKey,而是在具体的请求方法里手动添加key参数,比如:

request = youtube.channels().list(part="snippet", mine=True, key=options.api_key)

不过对于你当前的mine=true请求,完全不需要API Key,只需要保证Credentials被正确使用就够了。

修改后的完整代码

import argparse
import google.oauth2.credentials
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

def get_authenticated_service(options):
    creds = google.oauth2.credentials.Credentials(options.access_token)
    return build('youtube', 'v3', credentials=creds)

def list_channels(youtube, options):
    request = youtube.channels().list(part="snippet", mine=True)
    response = request.execute()
    print(response)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--api_key', required=True)
    parser.add_argument('--access_token', required=True)
    args = parser.parse_args()
    youtube = get_authenticated_service(args)
    try:
        list_channels(youtube, args)
    except HttpError as e:
        print('An HTTP error {0} occurred:\n{1}'.format(e.resp.status, e.content))

(注:虽然--api_key参数还在,但代码里已经不用它了,如果你确定之后也用不上,可以把这个参数删掉)

最后运行原来的命令就能正常拿到频道数据啦!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:02:42