多用户R Shiny应用Google账号认证与Drive访问问题排查
问题排查与修复方案
1. 凭证管理适配shinyapps.io
- 本地
credentials.json文件无法在shinyapps.io环境中直接读取,需改用环境变量传递凭证信息:- 从Google Cloud控制台下载的Web类型JSON凭证里,提取
client_id和client_secret。 - 在shinyapps.io的应用设置页面,添加三个环境变量:
GARGLE_CLIENT_ID:填入提取的client_idGARGLE_CLIENT_SECRET:填入提取的client_secretGARGLE_OAUTH_CACHE=FALSE:避免多用户认证时的缓存冲突
- 代码中替换原
gar_set_client代码为:gar_set_client( client_id = Sys.getenv("GARGLE_CLIENT_ID"), client_secret = Sys.getenv("GARGLE_CLIENT_SECRET"), scopes = c("https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/spreadsheets"), activate = "web" ) - 注意:不要将
credentials.json上传至shinyapps.io或版本控制系统,防止敏感信息泄露。
- 从Google Cloud控制台下载的Web类型JSON凭证里,提取
2. 统一多包认证上下文
googleAuthR、googledrive、googlesheets4均基于gargle包实现认证,需确保三者共享同一凭证:
server <- function(input, output, session){ # 执行认证并获取状态 auth <- gar_shiny_auth(session) # 认证完成后,让googledrive和googlesheets4复用当前凭证 observeEvent(auth, { googledrive::drive_auth(token = gar_get_token()) googlesheets4::gs4_auth(token = gar_get_token()) }) # 后续数据处理逻辑... }
3. 修正Google Sheet读取逻辑
原代码中drive_download是将文件下载到本地,而非返回文本内容,直接用googlesheets4读取更高效:
output$gdrive <- renderTable({ req(auth) # 强制等待认证完成后执行 file_name <- "Monitoring" # 精准查找Google Sheet类型文件 drive_file <- googledrive::drive_find( pattern = file_name, type = "spreadsheet", n_max = 1 # 仅取第一个匹配项 ) if(nrow(drive_file) > 0){ # 直接读取Sheet内容到数据框 Monitoring <- googlesheets4::read_sheet(drive_file$id) Monitoring } else { data.frame(提示 = "未找到名为Monitoring的Google Sheet") } })
完整修正后的代码
library("shiny") library("shinydashboard") library("shinyjs") library("googleAuthR") library("googlesheets4") library("googledrive") library("readxl") # 配置Google认证(适配shinyapps.io环境变量) gar_set_client( client_id = Sys.getenv("GARGLE_CLIENT_ID"), client_secret = Sys.getenv("GARGLE_CLIENT_SECRET"), scopes = c( "https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/spreadsheets" ), activate = "web" ) ## UI部分 ui <- fluidPage( title = "Google Drive 多用户访问演示", tableOutput("gdrive") ) ## Server部分 server <- function(input, output, session){ # 处理用户认证,返回认证状态 auth <- gar_shiny_auth(session) # 认证完成后,同步凭证至googledrive和googlesheets4 observeEvent(auth, { googledrive::drive_auth(token = gar_get_token()) googlesheets4::gs4_auth(token = gar_get_token()) }) output$gdrive <- renderTable({ req(auth) # 等待认证完成 file_name <- "Monitoring" # 查找目标Google Sheet drive_file <- googledrive::drive_find( pattern = file_name, type = "spreadsheet", n_max = 1 ) if(nrow(drive_file) > 0){ # 读取数据到变量Monitoring Monitoring <- googlesheets4::read_sheet(drive_file$id) Monitoring } else { data.frame(状态 = "未找到目标Google Sheet") } }) } shinyApp(gar_shiny_ui(ui), server)
部署额外注意事项
- 在Google Cloud项目的OAuth同意屏幕中,确保已添加所有需要访问应用的用户(测试阶段可选择“外部”类型,手动添加测试用户)
- 将shinyapps.io应用的完整URL(格式为
https://<你的应用名>.shinyapps.io/<应用名>/)添加到Google Cloud项目的“已授权的重定向URI”列表中
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

