如何避免Google Apps Script每周重复授权问题?
问题
我编写了一个关联Google表格的Google Apps Script,用于将表格数据导出为JSON文件,供自己开发的Android应用通过Web App的/exec链接访问。我需要数据公开可访问,无需用户在应用或浏览器中授权,因此将其设置为以部署者身份运行、允许任何人匿名访问。该设置最初可正常工作,但约一周后就会提示我重新授权。
配置截图
- Apps Script界面截图:

- 部署配置截图:

脚本代码
function doGet() { var sheetName = "EDIT"; // Replace with the name of your sheet var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName); if (!sheet) { return { error: "Sheet not found." }; } var data = sheet.getDataRange().getValues().map(([a,,c,d,e,f,g,,i,j,,,,,o,,q,r,s,t,u,v]) => [a,c,d,e,f,g,i,j,o,q,r,s,t,u,v]); var headers = data[0]; var jsonData = []; for (var i = 1; i < data.length; i++) { var row = data[i]; var rowObject = {}; for (var j = 0; j < headers.length; j++) { rowObject[headers[j]] = row[j]; } jsonData.push(rowObject); } console.log(jsonData) return ContentService.createTextOutput(JSON.stringify(jsonData)) .setMimeType(ContentService.MimeType.JSON); } function myFunction() { doGet(); }
appscript.json配置
{ "timeZone": "Europe/Berlin", "dependencies": {}, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8", "sheets": { "macros": [ { "menuName": "sort", "functionName": "sort", "defaultShortcut": "Ctrl+Alt+Shift+1" } ] }, "webapp": { "executeAs": "USER_DEPLOYING", "access": "ANYONE_ANONYMOUS" }, "executionApi": { "access": "MYSELF" } }
我了解这是Google的安全措施,但希望避免每周重新授权。我已尝试多数建议(包括正式部署应用),但仍无法长期解决。有人提到发布可能有效,但Google要求提交大量信息,请问是否有其他解决方案?
解决方案
1. 改用服务账号访问表格(最稳定方案)
绕开个人账号的授权过期限制,使用独立的服务账号对接表格:
- 登录Google Cloud Console,创建新项目后,在「IAM与管理」>「服务账号」中生成新的服务账号。
- 为服务账号下载JSON格式的密钥文件,妥善保存。
- 在目标Google表格的共享设置中,添加服务账号的邮箱地址,赋予「查看者」或「编辑者」权限(按需选择)。
- 修改Apps Script代码,通过OAuth2库使用服务账号认证访问表格:
function doGet() { // 替换为你的服务账号密钥内容 var serviceAccountKey = { "type": "service_account", "project_id": "你的项目ID", "private_key_id": "你的私钥ID", "private_key": "-----BEGIN PRIVATE KEY-----\n你的私钥内容\n-----END PRIVATE KEY-----\n", "client_email": "你的服务账号邮箱", "client_id": "你的客户端ID", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "你的证书URL" }; // 加载OAuth2库(需提前添加,库ID:1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF) var service = OAuth2.createService('SheetService') .setTokenUrl('https://oauth2.googleapis.com/token') .setPrivateKey(serviceAccountKey.private_key) .setIssuer(serviceAccountKey.client_email) .setPropertyStore(PropertiesService.getScriptProperties()) .setScope('https://www.googleapis.com/auth/spreadsheets.readonly'); // 只读权限足够则用此,需编辑换spreadsheets if (service.hasAccess()) { var spreadsheetId = "你的表格ID"; // 替换为目标表格ID var range = "EDIT!A:Z"; // 替换为需要读取的范围 var url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}`; var response = UrlFetchApp.fetch(url, { headers: { 'Authorization': 'Bearer ' + service.getAccessToken() } }); var rawData = JSON.parse(response.getContentText()).values; // 复用原有数据转换逻辑 var headers = rawData[0]; var jsonData = []; for (var i = 1; i < rawData.length; i++) { var row = rawData[i]; var rowObject = {}; for (var j = 0; j < headers.length; j++) { rowObject[headers[j]] = row[j] || ""; } jsonData.push(rowObject); } return ContentService.createTextOutput(JSON.stringify(jsonData)) .setMimeType(ContentService.MimeType.JSON); } else { return ContentService.createTextOutput(JSON.stringify({error: service.getLastError()})) .setMimeType(ContentService.MimeType.JSON); } }
2. 缩小权限范围
当前脚本默认请求完整的Google Sheets权限,缩小权限范围可降低安全触发概率:
- 在
appscript.json中添加明确的只读权限声明:"oauthScopes": [ "https://www.googleapis.com/auth/spreadsheets.readonly" ] - 重新部署Web App,授权时仅请求只读权限,减少安全机制的敏感度。
3. 设置定期触发保持授权有效
创建每日定时触发器,让脚本定期执行,避免因长期闲置导致授权过期:
- 在Apps Script编辑器左侧点击「触发器」图标,添加新触发器。
- 选择
doGet函数,事件源选「时间驱动」,类型选「每天」,设置固定时间运行。
4. 检查异常日志
查看Apps Script执行日志(「查看」>「日志」),如果存在频繁错误请求(如异常IP、过量调用),会被判定为风险操作导致授权提前过期。优化请求逻辑,避免不必要的重复调用。
内容的提问来源于stack exchange,提问作者dennisklad
相关产品推荐
相关产品推荐

