授权范围

用户必须授权访问其数据或代表其执行操作的脚本项目。当用户首次运行需要授权的脚本时,界面会显示一个提示,以启动授权流程。

在此流程中,界面会告知用户脚本请求哪些权限。例如,脚本可能会请求读取电子邮件或创建日历活动的权限。脚本项目会将这些单独的权限定义为 OAuth 范围

对于大多数脚本,Apps 脚本会自动检测所需的范围。您可以随时查看脚本使用的范围。您还可以使用网址字符串在清单明确设置范围。已发布的应用(例如插件)必须使用尽可能最小的范围。

在授权流程中,Apps 脚本会显示所需范围的人类可读说明。例如,如果脚本需要电子表格的只读权限,则清单可能包含 https://www.googleapis.com/auth/spreadsheets.readonly 范围。授权提示会要求用户允许此应用“查看您的 Google 电子表格”。

某些范围包含其他范围。例如,授权范围 https://www.googleapis.com/auth/spreadsheets 允许对电子表格进行读写操作。

对于某些界面(例如 Apps 脚本 IDE),用户会看到精细的 OAuth 权限请求页面。在此界面中,用户可以选择要授予的特定权限,而不是一次性授予所有权限。设计脚本以处理精细的 OAuth 权限

查看范围

如需查看脚本项目所需的范围,请执行以下操作:

  1. 打开脚本项目。
  2. 点击左侧的概览图标
  3. 查看项目 OAuth 范围 下的范围。

设置明确的范围

Apps 脚本会扫描代码中的函数调用,自动确定所需的范围。虽然这足以满足大多数脚本的需求,但对于已发布的插件、Web 应用、Chat 应用以及对 Chat API 的调用,您必须直接控制范围。

Apps 脚本有时会自动分配宽泛的范围。这可能意味着您的脚本向用户请求的权限超出了所需范围。对于已发布的脚本,请将宽泛的范围替换为有限的范围集,该范围集应涵盖脚本的需求。

您可以修改脚本项目的清单文件,明确设置脚本项目使用的范围。清单字段 oauthScopes 是项目使用的范围数组。如需设置项目的范围,请执行以下操作:

  1. 打开脚本项目。
  2. 点击左侧的项目设置图标
  3. 选中在编辑器中显示“appsscript.json”清单文件复选框。
  4. 点击左侧的编辑器
  5. 点击左侧的 appsscript.json 文件。
  6. 找到标记为 oauthScopes 的顶层字段。如果不存在,您可以添加该字段。
  7. oauthScopes 数组的内容替换为您希望项目使用的范围。例如:
          {
            ...
            "oauthScopes": [
              "https://www.googleapis.com/auth/spreadsheets.readonly",
              "https://www.googleapis.com/auth/userinfo.email"
            ],
           ...
          }
  8. 点击顶部的保存图标

处理精细的 OAuth 权限

精细的 OAuth 权限请求页面最初是在 Apps 脚本 IDE 中推出的,面向直接执行脚本的用户。随着时间的推移,权限请求页面将逐步推广到其他场景,例如宏、触发器和插件。如需了解详情,请参阅 Google Apps 脚本 IDE 执行中的精细 OAuth 权限请求

通过精细的 OAuth 权限请求页面,用户可以指定要授权的各个 OAuth 范围。这样,用户就可以精细地控制与每个脚本共享哪些账号数据。例如,如果某个脚本请求电子邮件范围和日历范围的权限,用户可以选择授予日历权限,但不授予 Gmail 权限。

以下部分介绍了如何处理精细的 OAuth 权限。

自动为必要的范围请求权限

如果执行流程需要特定范围,您可以要求用户授予这些权限。您的脚本可以检查权限,并在缺少权限时自动请求。

ScriptApp中的以下方法可验证权限并呈现授权提示:

示例

以下示例展示了如何调用 requireScopes()requireAllScopes()。该脚本使用 Gmail、Google 表格和 Google 日历的范围。sendEmail() 函数仅需要 Gmail 和 Google 表格的权限范围,而 createEventSendEmail() 函数需要脚本使用的所有权限范围。

// This function requires the Gmail and Sheets scopes.
function sendEmail() {
  // Validates that the user has granted permission for the Gmail and Sheets scopes.
  // If not, the execution ends and prompts the user for authorization.
  ScriptApp.requireScopes(ScriptApp.AuthMode.FULL, [
    'https://mail.google.com/',
    'https://www.googleapis.com/auth/spreadsheets'
  ]);

  // Sends an email.
  GmailApp.sendEmail("dana@example.com", "Subject", "Body");
  Logger.log("Email sent successfully!");

  // Opens a spreadsheet and sheet to track the sent email.
  const ss = SpreadsheetApp.openById("abc1234567");
  const sheet = ss.getSheetByName("Email Tracker")

  // Gets the last row of the sheet.
  const lastRow = sheet.getLastRow();

  // Adds "Sent" to column E of the last row of the spreadsheet.
  sheet.getRange(lastRow, 5).setValue("Sent");
  Logger.log("Sheet updated successfully!");
}

// This function requires all scopes used by the script (Gmail,
// Calendar, and Sheets).
function createEventSendEmail() {
  // Validates that the user has granted permission for all scopes used by the
  // script. If not, the execution ends and prompts the user for authorization.
  ScriptApp.requireAllScopes(ScriptApp.AuthMode.FULL);

  // Creates an event.
  CalendarApp.getDefaultCalendar().createEvent(
    "Meeting",
    new Date("November 28, 2024 10:00:00"),
    new Date("November 28, 2024 11:00:00")
  );
  Logger.log("Calendar event created successfully!");

  // Sends an email.
  GmailApp.sendEmail("dana@example.com", "Subject 2", "Body 2");
  Logger.log("Email sent successfully!");

  // Opens a spreadsheet and sheet to track the created meeting and sent email.
  const ss = SpreadsheetApp.openById("abc1234567");
  const sheet = ss.getSheetByName("Email and Meeting Tracker")
  // Gets the last row
  const lastRow = sheet.getLastRow();

  // Adds "Sent" to column E of the last row
  sheet.getRange(lastRow, 5).setValue("Sent");
  // Adds "Meeting created" to column F of the last row
  sheet.getRange(lastRow, 6).setValue("Meeting created");
  Logger.log("Sheet updated successfully!");
}

为缺失的范围创建自定义体验

您可以检索用户的权限状态,并设计自定义体验。 例如,您可以停用需要缺少权限的功能,或显示一个对话框来解释相关要求。以下方法会检索一个包含用户权限信息的对象,其中包括用户已授权的范围以及一个用于请求缺失范围的网址:

如需从授权信息对象中获取权限详细信息,例如授权范围列表和用于请求缺失权限的网址,请使用 AuthorizationInfo中的方法。

示例

以下示例展示了如何使用 getAuthorizationInfo() 跳过用户未授予所需范围的功能。这样一来,其余执行流程便可继续,而不会提示缺少相应范围的授权。

// This function uses the Gmail scope and skips the email
// capabilities if the scope for Gmail hasn't been granted.
function myFunction() {
  const authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL, ['https://mail.google.com/']);
  if (authInfo.getAuthorizationStatus() === ScriptApp.AuthorizationStatus.NOT_REQUIRED) {
    GmailApp.sendEmail("dana@example.com", "Subject", "Body");
    Logger.log("Email sent successfully!");
  } else {
    const scopesGranted = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL).getAuthorizedScopes();
    console.warn(`Authorized scopes: ${scopesGranted} not enough to send mail, skipping.`);
  }
  // Continue the rest of the execution flow...
}

确保触发器执行具有权限

与触发器关联的函数会自动运行,用户可能不在场,无法提供权限。建议您在安装触发器之前使用 requireScopes(authMode, oAuthScopes)。此方法会提示用户授予缺失的权限,并且不允许在未授予这些权限的情况下安装触发器。

示例

// This function requires scope Sheets.
function trackFormSubmissions(e){
  // Opens a spreadsheet to track the sent email.
  const ss = SpreadsheetApp.openById("abc1234567");
  const sheet = ss.getSheetByName("Submission Tracker")

  // Gets the last row of the sheet.
  const lastRow = sheet.getLastRow();

  // Adds email address of user that submitted the form
  // to column E of the last row of the spreadsheet.
  sheet.getRange(lastRow, 5).setValue(e.name);
  Logger.log("Sheet updated successfully!");
}

function installTrigger(){
  // Validates that the user has granted permissions for trigger
  // installation and execution. If not, trigger doesn't get
  // installed and prompts the user for authorization.
  ScriptApp.requireScopes(ScriptApp.AuthMode.FULL, [
    'https://www.googleapis.com/auth/script.scriptapp',
    'https://www.googleapis.com/auth/spreadsheets',
    'https://www.googleapis.com/auth/forms.currentonly'
  ]);
  ScriptApp.newTrigger('trackFormSubmission')
    .forForm(FormApp.getActiveForm())
    .onFormSubmit()
    .create();
}

OAuth 验证

某些 OAuth 范围是敏感范围,因为它们允许访问 Google 用户数据。如果您的脚本项目使用的范围允许访问用户数据,则该项目必须先通过 OAuth 客户端验证,然后才能作为 Web 应用或插件公开发布。如需了解详情,请参阅以下指南:

受限范围

除了敏感范围之外,某些范围还被归类为受限范围,并受有助于保护用户数据的额外规则的约束。如果您发布的应用使用受限范围,则必须遵守所有规范。

在发布之前,请查看受限范围的完整列表。合规应用必须遵守有关特定 API 范围的其他要求

请尽可能避免使用受限范围,以简化审核流程。您可以为非公开应用随意使用受限范围。