如何在R中借助HTTR自动完成YouTube OAuth身份验证与重验证
解决方案
核心原因
报错本质是两个问题叠加:
- 手动读取RDS格式的令牌文件后,httr在内存中自动刷新的新令牌(包含新的access token和最新的refresh token)没有被写回本地文件,下次读取还是旧的refresh token,Google会判定旧refresh token失效,触发
invalid_grant报错 - 如果你在Google Cloud的OAuth应用是测试状态,refresh token默认7天过期,也会触发同类报错
方案1:使用httr自带的缓存机制实现自动更新(推荐)
httr的oauth2.0_token原生支持自定义缓存路径,只要设置cache参数为你的自定义令牌文件路径,就会自动实现:本地文件不存在时走授权流程,文件存在时直接读取,令牌刷新后自动将最新凭证写回该文件,不需要手动读写RDS。
修改后的初始化代码:
# 替换为对应频道的令牌文件路径,两个频道分别设置不同路径即可 tokenFile <- ".httr-oauth-channel1" if (is.null(appId) | is.null(appSecret)) { stop("Missing App Credentials") } token <- httr::oauth2.0_token( httr::oauth_endpoints("google"), httr::oauth_app("google", appId, appSecret), scope = c("https://www.googleapis.com/auth/youtube.readonly", "https://www.googleapis.com/auth/yt-analytics.readonly"), # 核心参数:指定缓存文件路径,httr自动处理读写更新 cache = tokenFile )
配套请求逻辑修改:
不需要在循环里重复读取令牌文件,只需要初始化一次token对象即可,httr会自动处理刷新和缓存更新:
myData <- list() # 两个频道分别初始化对应token后发起请求即可 for(i in 1:2){ url <- paste0("https://youtube.googleapis.com/youtube/v3/videos?part=contentDetails%2Csnippet", "&id=",videoId) request <- GET(url, config(token = token)) myData[[i]] <- request }
方案2:手动控制令牌存储
如果需要自定义控制存储逻辑,可以在每次令牌刷新后手动将最新token对象写回文件:
# 每次请求后检查令牌是否更新,写入文件 request <- GET(url, config(token = token)) # 强制刷新后存储(也可以定时检查expires_at字段判断是否需要刷新) if (token$credentials$expires_at < Sys.time()) { token$refresh() saveRDS(token, tokenFile) }
必须注意的Google API规则
- 进入Google Cloud控制台,将你的OAuth应用从「测试状态」改为「发布状态」,否则refresh token会默认7天过期,必须重新授权
- 同一个Google账号同一套scope下最多生成50个有效refresh token,超出后最早生成的会自动失效,不要重复触发授权流程
- 两个频道的令牌要分开存到不同的文件,不要共用同一个缓存文件,避免刷新冲突
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

