R中使用bigrquery切换Google账号失败,求助问题原因与解决方法
问题:bigrquery切换Google账号失败的排查与解决
背景
我用R的bigrquery包,需要在两个Google账号间切换:一个是关联工作的账号,另一个是个人账号,用来测试数据治理机制。但调用bq_auth()切换账号时,始终绑定工作账号;用gargle::token_fetch()却能成功切换,还遇到了和权限范围(scope)相关的奇怪现象。
复现过程
bq_auth切换账号失败
> bq_auth(email="acct1@work.com") > bq_has_token() [1] TRUE > bq_user() [1] "acct1@work.com" > bq_deauth() > bq_has_token() [1] FALSE > bq_auth(email = "personal@gmail.com") > bq_has_token() [1] TRUE > bq_user() [1] "acct1@work.com" > bq_deauth() > bq_has_token() [1] FALSE > bq_user() NULL
成功切换的方式
tkn2 = gargle::token_fetch(email="personal@gmail.com") > bq_user() [1] "personal@gmail.com"
权限范围(scope)相关的奇怪现象
cred0 <- gargle::token_fetch(email = "personal@gmail.com") cred1 <- gargle::token_fetch(email = "personal@gmail.com",scopes = c("https://www.googleapis.com/auth/bigquery", "https://www.googleapis.com/auth/cloud-platform")) > gargle::token_userinfo(cred0)$email [1] "personal@gmail.com" > gargle::token_userinfo(cred1)$email [1] "acct1@work.com"
Session信息
R version 4.3.0 (2023-04-21) Platform: aarch64-apple-darwin20 (64-bit) Running under: macOS 14.3 Matrix products: default BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0 locale: [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 time zone: America/New_York tzcode source: internal attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] bigrquery_1.4.2 lubridate_1.9.2 forcats_1.0.0 stringr_1.5.0 dplyr_1.1.3 purrr_1.0.1 readr_2.1.4 [8] tidyr_1.3.0 tibble_3.2.1 ggplot2_3.4.2 tidyverse_2.0.0 devtools_2.4.5 usethis_2.2.0 loaded via a namespace (and not attached): [1] gtable_0.3.3 xfun_0.39 htmlwidgets_1.6.2 remotes_2.4.2 processx_3.8.1 gargle_1.5.0 [7] callr_3.7.3 tzdb_0.4.0 vctrs_0.6.4 tools_4.3.0 ps_1.7.5 generics_0.1.3 [13] curl_5.1.0 parallel_4.3.0 fansi_1.0.4 pkgconfig_2.0.3 dbplyr_2.4.0 assertthat_0.2.1 [19] readxl_1.4.2 lifecycle_1.0.3 compiler_4.3.0 munsell_0.5.0 httpuv_1.6.11 htmltools_0.5.5 [25] yaml_2.3.7 later_1.3.1 pillar_1.9.0 crayon_1.5.2 urlchecker_1.0.1 ellipsis_0.3.2 [31] openssl_2.0.6 cachem_1.0.8 sessioninfo_1.2.2 mime_0.12 tidyselect_1.2.0 digest_0.6.33 [37] stringi_1.7.12 fastmap_1.1.1 grid_4.3.0 archive_1.1.5 colorspace_2.1-0 cli_3.6.1 [43] magrittr_2.0.3 pkgbuild_1.4.1 utf8_1.2.3 withr_2.5.0 rappdirs_0.3.3 prettyunits_1.1.1 [49] scales_1.2.1 promises_1.2.0.1 bit64_4.0.5 timechange_0.2.0 rmarkdown_2.22 httr_1.4.6 [55] bit_4.0.5 cellranger_1.1.0 askpass_1.1 hms_1.1.3 memoise_2.0.1 shiny_1.7.4 [61] evaluate_0.21 knitr_1.43 miniUI_0.1.1.1 profvis_0.3.8 rlang_1.1.1 Rcpp_1.0.10 [67] DBI_1.1.3 xtable_1.8-4 glue_1.6.2 pkgload_1.3.2 vroom_1.6.3 rstudioapi_0.14 [73] jsonlite_1.8.5 R6_2.5.1 fs_1.6.2
原因分析与解决方法
1. bq_auth切换失败的核心原因
bigrquery依赖gargle包处理认证,bq_auth()默认会优先复用本地缓存的令牌。如果工作账号的令牌已经缓存,且覆盖了bigrquery所需的权限范围,即使指定新的邮箱,gargle也会直接复用该缓存,不会触发新的OAuth验证流程。
bq_deauth()只是清除当前会话的令牌,不会删除本地缓存的令牌文件,所以再次调用bq_auth()时仍会复用旧缓存。
2. 解决方法
方法一:清除指定账号的缓存令牌
删除工作账号的缓存后,再重新认证个人账号:
# 删除工作账号的缓存令牌 gargle::gargle_oauth_cache_delete("acct1@work.com") # 若需要清除所有缓存令牌(谨慎操作) # gargle::gargle_oauth_cache_clean() # 重新认证个人账号 bq_auth(email = "personal@gmail.com", cache = TRUE)
方法二:禁用缓存强制重新认证
调用bq_auth()时关闭缓存,强制弹出浏览器窗口验证:
bq_deauth() bq_auth(email = "personal@gmail.com", cache = FALSE)
注意:这种方式不会缓存令牌,每次都需要重新验证,适合临时测试。
方法三:手动传入令牌(最可靠)
用gargle::token_fetch()获取个人账号的令牌,再手动传给bq_auth():
# 获取适配bigrquery权限的个人账号令牌 personal_token <- gargle::token_fetch(email = "personal@gmail.com", scopes = bigrquery::bq_auth_scopes()) # 传入bigrquery完成认证 bq_auth(token = personal_token)
3. 权限范围相关现象的解释
调用gargle::token_fetch(email = "personal@gmail.com")时,使用的是默认基础权限范围,缓存中没有对应个人账号的令牌,所以触发了新的认证。
而指定bigrquery所需的权限范围时,gargle检查到工作账号已有对应范围的缓存令牌,直接复用了该缓存,因此返回工作账号的信息。解决方式同样是清除对应范围的缓存,或禁用缓存重新认证。
内容的提问来源于stack exchange,提问作者HowYaDoing
相关产品推荐
相关产品推荐

