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

适配Unity调用的Google Web App用户授权弹窗实现咨询

现有代码的核心失效原因
  • onOpen()是Google Sheets/文档容器触发的自动函数,你在doGet里手动调用它时,函数内部创建的HtmlOutput对象只是存在内存里的临时变量,没有作为返回值推送给前端,自然不会弹出任何窗口。
  • 当前doGet不做任何授权状态判断,上来就直接调用表格读取逻辑。当Web App设置为“以你的身份执行”时,所有用户的请求都借用你的权限跑,平台永远不会触发面向其他用户的授权弹窗;如果切到“以用户身份执行”,未授权用户直接读取表格会触发权限报错,连可交互的引导页面都拿不到。
  • 用Unity的UnityWebRequest发纯接口请求时,就算后端返回了HTML授权页,客户端也只会把内容当纯文本解析,根本没有渲染、弹出交互窗口的能力。
正确落地实现步骤

基础配置调整

首先把Web App的部署权限配置改成:

  • 执行身份:以访问应用的用户身份执行
  • 访问权限:允许所有拥有链接的用户访问
    这个配置是触发Google官方用户授权流程的前提——只要你的代码用到了需要用户授权的服务(比如读取Spreadsheet、读写UserProperties),平台会自动在用户第一次访问时拦截请求,重定向到Google标准的授权同意页,你不需要手动写代码拉取弹窗。

后端逻辑改造

抛弃之前“调用onOpen弹窗”的逻辑,直接在doGet里做分支判断,根据授权状态返回对应的内容:

  • 未授权状态:返回带操作按钮的HTML引导页,引导用户完成授权
  • 已授权状态:再执行原来的表格读取、返回JSON数据的逻辑
    你自己写的authorize函数只需要做两件事:把授权标记写到UserProperties里,返回提示页面引导用户返回客户端,不需要额外处理平台层面的授权流程。

前端(Unity)适配调整

受Google授权流程的限制,纯接口请求无法完成授权交互,必须做流程跳转:

  • Unity第一次发起Get请求时,如果收到未授权的响应/接口权限报错,直接调用系统浏览器打开Web App的公开访问链接
  • 用户在浏览器环境下走完Google的官方授权流程、点击页面上的授权按钮完成业务标记后,关闭浏览器返回Unity
  • Unity重新发起Get请求,此时后端已经能识别到授权状态,直接返回所需的JSON数据
可直接参考的改造后代码
// 业务授权完成标记函数
function authorize(){
  // 写入授权状态
  UserProperties.setProperty('author','yes');
  // 返回授权完成提示页
  return HtmlService.createHtmlOutput(`
    <div style="padding: 2rem; font-family: system-ui;">
      <h3>授权已完成</h3>
      <p>你可以关闭当前页面,回到客户端继续操作。</p>
    </div>
  `).setTitle("授权确认");
}

function doGet(e){
  // 优先校验授权状态,不要直接读取表格
  const hasAuth = UserProperties.getProperty('author');
  
  // 未授权分支:返回授权引导页
  if(!hasAuth){
    const authUrl = ScriptApp.getService().getUrl({path: '/authorize'});
    return HtmlService.createHtmlOutput(`
      <div style="padding: 2rem; font-family: system-ui; max-width: 400px;">
        <h3>应用需要授权才能访问关联的Google Sheets数据</h3>
        <p>点击下方按钮即可完成授权流程</p>
        <button 
          onclick="window.location.href='${authUrl}'"
          style="padding: 0.75rem 1.5rem; background: #1a73e8; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem;"
        >
          完成授权
        </button>
      </div>
    `).setTitle("授权引导");
  }

  // 已授权分支:执行原有数据读取逻辑
  const activeSheet = SpreadsheetApp.getActiveSheet();
  const values = [];
  // 读取第1行目标列数据
  for(let i = 3; i <= 16; i++){
    const columnChar = String.fromCharCode('A'.charCodeAt() + i);
    values.push(activeSheet.getRange(`${columnChar}1`).getValue());
  }
  // 读取第2行目标列数据
  for(let i = 3; i <= 16; i++){
    const columnChar = String.fromCharCode('A'.charCodeAt() + i);
    values.push(activeSheet.getRange(`${columnChar}2`).getValue());
  }

  // 返回JSON格式数据
  return ContentService.createTextOutput(JSON.stringify({result: values}))
    .setMimeType(ContentService.MimeType.JSON);
}
常见踩坑提醒
  • 所有推送给前端的HTML内容,必须是doGet的直接返回值,不要在中间函数里创建HtmlOutput对象却不return,否则前端根本接收不到。
  • Google的官方授权弹窗是平台自动触发的,不需要手动调用接口拉取:只要代码以用户身份执行、且触发了需要授权的操作,平台就会自动弹出授权页。之前看不到弹窗的核心原因,是一直使用“以你的身份执行”的部署配置,平台不需要向其他用户索要权限。
  • 不要尝试在Unity客户端内直接嵌入授权流程:Google的授权页有严格的域名校验,第三方客户端无法直接承接授权重定向,必须引导用户跳转到系统浏览器完成操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 12:24:03