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

多用户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_id
      • GARGLE_CLIENT_SECRET:填入提取的client_secret
      • GARGLE_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或版本控制系统,防止敏感信息泄露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:17:47