适用于客户端 Web 应用的 OAuth 2.0

本文档介绍了如何实现 OAuth 2.0 授权来访问 通过 JavaScript Web 应用访问 Google API。OAuth 2.0 允许用户 与应用程序共享特定数据 ,同时保留应用程序的用户名、密码和其他 私密信息。 例如,应用可以使用 OAuth 2.0 从 用户在 Google 云端硬盘中存储文件。

此 OAuth 2.0 流程称为隐式授权流程。设计用于 访问 API 的应用。这些 不能存储机密信息。

在此流程中,您的应用会打开一个 Google 网址,该网址使用查询参数来识别您的应用 以及应用所需的 API 访问权限类型您可以在当前浏览器中打开该网址 窗口或弹出式窗口用户可以向 Google 进行身份验证并授予其请求的权限。 然后,Google 会将用户重定向回您的应用。重定向包含访问令牌, 您的应用会进行验证,然后使用它来发出 API 请求。

Google API 客户端库和 Google Identity 服务

如果您使用适用于 JavaScript 的 Google API 客户端库 向 Google 进行授权调用时,您应使用 Google Identity 服务 JavaScript 库来处理 OAuth 2.0 流程。请查看 Google 身份服务词元模型,也就是 基于 OAuth 2.0 隐式授权流程

前提条件

为您的项目启用 API

任何调用 Google API 的应用都需要在 API Console。

如需为您的项目启用该 API,请按以下步骤操作:

  1. Open the API Library 在 Google API Console。
  2. If prompted, select a project, or create a new one.
  3. API Library 列出了所有可用的 API(按产品分组) 家庭和受欢迎程度。如果列表中没有显示您要启用的 API,请使用搜索功能 找到,或在产品系列中点击查看全部
  4. 选择您要启用的 API,然后点击启用按钮。
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

创建授权凭据

任何使用 OAuth 2.0 访问 Google API 的应用都必须具有授权凭据 来向 Google 的 OAuth 2.0 服务器标识应用以下步骤说明了如何 为项目创建凭据然后,您的应用就可以使用这些凭据访问 API 为该项目启用的功能

  1. Go to the Credentials page.
  2. 依次点击创建凭据 > OAuth 客户端 ID
  3. 选择 Web 应用应用类型。
  4. 填写表单。 使用 JavaScript 发出已获授权的 Google API 请求的应用 必须指定已获授权的 JavaScript 源。该源用于识别 以便您的应用向 OAuth 2.0 服务器发送请求这些源必须遵守 Google 的验证规则

确定访问权限范围

范围让您的应用可以仅请求访问所需的资源,同时 让用户能够控制他们向您的应用授予的访问权限大小。因此, 请求的范围数量与可能性 征得用户同意。

在开始实现 OAuth 2.0 授权之前,我们建议您确定范围 您的应用需要获取访问权限的请求。

OAuth 2.0 API 范围文档包含完整的 可用于访问 Google API 的范围列表。

获取 OAuth 2.0 访问令牌

以下步骤展示了您的应用如何与 Google 的 OAuth 2.0 服务器交互,以获取 用户同意代表其执行 API 请求。您的应用必须具有 然后才能执行需要用户授权的 Google API 请求。

第 1 步:重定向到 Google 的 OAuth 2.0 服务器

要请求访问用户数据的权限,请将用户重定向到 Google 的 OAuth 2.0 服务器。

OAuth 2.0 端点

生成一个网址以从 Google 的 OAuth 2.0 端点请求访问权限,网址为 https://accounts.google.com/o/oauth2/v2/auth。可通过 HTTPS 访问此端点; 普通 HTTP 连接会被拒绝。

Google 授权服务器支持以下网页的查询字符串参数: 服务器应用:

参数
client_id 必需

应用的客户端 ID。您可以在 API Console Credentials page

redirect_uri 必需

确定 API 服务器在用户完成 授权流程。该值必须与以下对象的某个授权重定向 URI 完全匹配: OAuth 2.0 客户端(在客户端的 API Console Credentials page。如果此值与 获得授权的重定向 URI,client_id 您将获得 redirect_uri_mismatch 个错误。

请注意,httphttps 架构、大小写和尾随斜杠 (“/”)必须全部匹配。

response_type 必需

JavaScript 应用需要将该参数的值设置为 token。这个 值指示 Google 授权服务器将访问令牌作为 name=value 对的 URI 的片段标识符 (#) 用户在完成授权流程后将被重定向。

scope 必需

答 空格分隔 范围列表,用于标识您的应用可以在 。这些值会告知 Google 向 用户。

范围让您的应用可以仅请求访问所需的资源 同时让用户能够控制他们向您的网页授予 应用。因此,所请求的范围数量与 以及征得用户同意的可能性

我们建议您的应用在上下文中请求对授权范围的访问权限 。视情况请求访问用户数据,方法为: 增量授权,可以帮助用户更轻松地 了解您的应用为何需要其请求的访问权限。

state 建议

指定应用用来维持 授权请求和授权服务器的响应。 服务器返回您作为 name=value 对在 网址片段标识符 (#) 的 redirect_uri(在用户同意或拒绝您的应用的声明之后) 权限申请。

此参数有多种用途,例如将用户定向到 您应用中的正确资源、发送 Nonce 以及缓解跨网站请求 。由于您的 redirect_uri 可以被猜到,因此使用 state 值可以更好地确保传入的连接是 身份验证请求。如果您生成了随机字符串或对 Cookie 的哈希值或 另一个用于捕获客户端状态的值,您可以验证对 此外,请确保请求和响应来自同一个浏览器, 以防范此类攻击,例如 跨网站请求 伪造行为。请参阅 OpenID Connect 关于如何创建和确认 state 令牌的示例的文档。

include_granted_scopes 可选

允许应用使用增量授权来请求访问 范围。如果您将此参数的值设置为 true,并且将 授权请求,那么新的访问令牌还将涵盖用于 用户之前已向应用授予访问权限请参阅 增量授权部分。

login_hint 可选

如果您的应用知道哪个用户正在尝试进行身份验证,则可以使用此参数 ,以便向 Google 身份验证服务器提供提示。服务器会使用该提示 简化登录流程:在登录表单中预先填写电子邮件地址字段 选择相应的多登录会话。

将该参数值设为电子邮件地址或 sub 标识符,即 等同于用户的 Google ID。

prompt 可选

一系列要向用户显示的提示(用空格分隔,区分大小写)。如果您 指定此参数,系统仅会在首次您的项目时提示用户 请求访问权限。请参阅 提示再次征求用户意见

可能的值包括:

none 不得显示任何身份验证页面或权限请求页面。不得使用 其他值
consent 提示用户同意。
select_account 提示用户选择账号。

到 Google 授权服务器的重定向示例

下面显示了一个示例网址,其中的换行符和空格以方便阅读。

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

创建请求网址后,将用户重定向到该网址。

JavaScript 示例代码

以下 JavaScript 代码段展示了如何在 而无需使用适用于 JavaScript 的 Google API 客户端库。由于此 OAuth 2.0 端点不支持跨源资源共享 (CORS),该代码段会创建一个 表单。

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

第 2 步:Google 提示用户同意

在此步骤中,用户可决定是否授予您的应用所请求的访问权限。目前 阶段,Google 会显示一个意见征求窗口,其中会显示您的应用名称和 Google API 它请求权限的那些服务,可以使用用户的授权凭据 要授予的访问权限范围的摘要。通过 然后,用户可以同意授予对您的应用请求的一个或多个范围的访问权限,或者 拒绝请求

在此阶段,您的应用无需进行任何操作,因为它会等待来自 Google 的 OAuth 2.0 服务器,指示是否已授予任何访问权限。该回答在 。

错误

向 Google 的 OAuth 2.0 授权端点发送的请求可能会显示面向用户的错误消息 而不是预期的身份验证和授权流程。常见错误代码和建议 分辨率。

admin_policy_enforced

由于以下政策,该 Google 账号无法对所请求的一个或多个范围进行授权 Google Workspace 管理员。参阅 Google Workspace 管理员帮助文章 您可以控制哪些第三方和内部应用访问 Google Workspace 数据 ,详细了解管理员如何限制对所有范围或敏感 限制范围,直到明确授予对 OAuth 客户端 ID 的访问权限。

disallowed_useragent

授权端点显示在 Google 禁止的嵌入式用户代理中。 OAuth 2.0 政策

Android

Android 开发者在以下位置打开授权请求时可能会遇到此错误消息: android.webkit.WebView。 开发者应该改用 Android 库,如 适用于 Android 的 Google 登录或 OpenID Foundation 的 适用于 Android 的 AppAuth

当 Android 应用在 用户从 Google 的 OAuth 2.0 授权端点转到 Google 的 OAuth 2.0 授权端点, 。开发者应该允许在 操作系统,其中包括 Android 应用链接 处理程序或默认浏览器应用。通过 Android 自定义标签页 也是一个受支持的选项。

iOS

iOS 和 macOS 开发者在以下位置打开授权请求时可能会遇到此错误: WKWebView。 开发者应该改用 iOS 库,如 iOS 版 Google 登录或 OpenID Foundation 的 适用于 iOS 的 AppAuth

当 iOS 或 macOS 应用在以下位置打开常规网页链接时,Web 开发者可能会遇到此错误 嵌入的用户代理,而用户从 Google 的 OAuth 2.0 授权端点 。开发者应该允许在 操作系统,其中包括 通用链接 处理程序或默认浏览器应用。通过 SFSafariViewController 也是一个受支持的选项。

org_internal

请求中的 OAuth 客户端 ID 属于某个项目 具体 Google Cloud Organization(Google Cloud 组织)。 有关此配置选项的详细信息,请参阅 用户类型 部分。

invalid_client

发出该请求的来源未获得此客户端的授权。请参阅 origin_mismatch

invalid_grant

使用增量授权时,令牌可能已过期 或已失效。 再次对用户进行身份验证,并请求用户同意以获取新令牌。如果您选择继续 请确定您的应用已正确配置, 在请求中使用正确的令牌和参数。否则,该用户账号可能具有 已被删除或停用。

origin_mismatch

发起授权请求的 JavaScript 的架构、域名和/或端口不得 与为 OAuth 客户端 ID 注册的授权 JavaScript 源 URI 相匹配。审核已授权 Google API Console中的 JavaScript 来源 Credentials page

redirect_uri_mismatch

授权请求中传递的 redirect_uri 与已获授权的 OAuth 客户端 ID 的重定向 URI。请在以下位置查看已获授权的重定向 URI: Google API Console Credentials page

发起授权请求的 JavaScript 的架构、域名和/或端口不得 与为 OAuth 客户端 ID 注册的授权 JavaScript 源 URI 相匹配。评价 授权的 JavaScript 来源 Google API Console Credentials page

redirect_uri 参数可以是指具有以下特征的 OAuth 带外 (OOB) 流程: 已弃用,不再受支持。请参阅 迁移指南,更新您的 集成。

invalid_request

您提出的请求出了点问题。造成这种情况的原因有很多:

  • 该请求的格式不正确
  • 请求缺少必需的参数
  • 请求使用的授权方法不受 Google 支持。验证您的 OAuth 集成使用推荐的集成方法

第 3 步:处理 OAuth 2.0 服务器响应

OAuth 2.0 端点

OAuth 2.0 服务器将响应发送至 redirect_uri 访问令牌请求。

如果用户批准了请求,则响应中会包含一个访问令牌。如果用户 未批准请求,则响应包含错误消息。访问令牌或 会在重定向 URI 的哈希代码段中返回错误消息,如下所示:

  • 访问令牌响应:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    除了 access_token 参数之外,fragment 字符串还具有 包含 token_type 参数,该参数始终设置为 Bearerexpires_in 参数,该参数用于指定 (以秒为单位)。如果指定了 state 参数 ,那么其值也会包含在响应中。

  • 错误响应:
    https://oauth2.example.com/callback#error=access_denied

OAuth 2.0 服务器响应示例

您可以点击以下示例网址测试此流程 拥有查看 Google 云端硬盘中文件元数据的只读权限:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

完成 OAuth 2.0 流程后,系统会将您重定向至 http://localhost/oauth2callback。该网址会生成 404 NOT FOUND 错误,除非您的本地机器恰好在以下位置传送文件: 该地址下一步会详细介绍 用户被重定向回您的应用时的 URI。

调用 Google API

OAuth 2.0 端点

在您的应用获得访问令牌后,您就可以使用该令牌调用 Google 代表指定的 用户账号(如果已授予 API 所需的访问权限范围)。为此,请添加 通过添加 access_token 查询来获取对 API 的请求中的访问令牌 参数或 Authorization HTTP 标头 Bearer 值。如有可能, 最好使用 HTTP 标头,因为查询字符串通常会显示在服务器日志中。大多数 可以使用客户端库来设置对 Google API 的调用(例如, 调用 Drive Files API)。

您可以访问以下网址,试用所有 Google API 并查看其作用域: OAuth 2.0 Playground

HTTP GET 示例

drive.files 端点(Drive Files API),同时使用 Authorization: Bearer HTTP 可能如下所示。请注意,您需要指定自己的访问令牌:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

以下是使用 access_token 为经过身份验证的用户对同一 API 的调用 查询字符串参数:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

curl 示例

您可以使用 curl 命令行应用测试这些命令。这里有 使用 HTTP 标头选项的示例(首选):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

或者,也可以使用查询字符串参数选项:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

JavaScript 示例代码

以下代码段演示了如何使用 CORS(跨源资源共享)将 向 Google API 发出请求。本示例未使用 JavaScript 版 Google API 客户端库。 不过,即使您没有使用客户端库, 该库文档中的 CORS 支持指南可能会对您有所帮助 以便更好地了解这些请求

在此代码段中,access_token 变量表示您拥有的 获取并代表授权用户发出 API 请求。完整的 示例演示了如何将该令牌存储在浏览器的本地存储空间中并检索该令牌 。

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

完整示例

OAuth 2.0 端点

此代码示例演示了如何在不使用 适用于 JavaScript 的 Google API 客户端库。该代码适用于显示按钮的 HTML 网页, 尝试 API 请求。如果您点击该按钮,代码会检查网页是否已存储了 浏览器的本地存储空间中的 API 访问令牌。如果是,则执行 API 请求。否则 系统就会启动 OAuth 2.0 流程

对于 OAuth 2.0 流程,该页面遵循以下步骤:

  1. 它会将用户定向到 Google 的 OAuth 2.0 服务器,该服务器会请求访问 https://www.googleapis.com/auth/drive.metadata.readonly 范围。
  2. 授予(或拒绝)对一个或多个请求范围的访问权限后,用户会被重定向到 原始网页,该网页从片段标识符字符串中解析访问令牌。
  3. 该页面使用访问令牌来发出示例 API 请求。

    API 请求调用 Drive API 的 about.get 方法,以检索 有关已获授权用户的 Google 云端硬盘账号的信息。

  4. 如果请求成功执行,则 API 响应会记录在浏览器的调试部分 控制台。

您可以通过 权限页面 Google 账号。该应用会被列为适用于 Google API 文档的 OAuth 2.0 演示

如需在本地运行此代码,您需要为 YOUR_CLIENT_IDYOUR_REDIRECT_URI 变量,与您的 授权凭据YOUR_REDIRECT_URI 变量 应设置为与该网页相同的网址。该值必须与以下项之一完全匹配: OAuth 2.0 客户端的授权重定向 URI(您在 API Console Credentials page。如果 此值与已获授权的 URI 不匹配,则您会收到 redirect_uri_mismatch 错误。您的项目还必须 为此请求启用了相应的 API

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var fragmentString = location.hash.substring(1);
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0 && params['state']) {
    if (params['state'] == localStorage.getItem('state')) {
      localStorage.setItem('oauth2-test-params', JSON.stringify(params) );

      trySampleRequest();
    } else {
      console.log('State mismatch. Possible CSRF attack');
    }
  }

  // Function to generate a random state value
  function generateCryptoRandomState() {
    const randomValues = new Uint32Array(2);
    window.crypto.getRandomValues(randomValues);

    // Encode as UTF-8
    const utf8Encoder = new TextEncoder();
    const utf8Array = utf8Encoder.encode(
      String.fromCharCode.apply(null, randomValues)
    );

    // Base64 encode the UTF-8 data
    return btoa(String.fromCharCode.apply(null, utf8Array))
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=+$/, '');
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // create random state value and store in local storage
    var state = generateCryptoRandomState();
    localStorage.setItem('state', state);

    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': state,
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

JavaScript 源验证规则

为帮助您 来保障应用的安全您的 JavaScript 源必须遵守这些规则。 如需 域名、主机和架构的定义(如下所述)。

验证规则
架构

JavaScript 来源必须使用 HTTPS 架构,而不是普通的 HTTP。Localhost URI (包括 localhost IP 地址 URI)不受此规则限制。

主机

主机不能是原始 IP 地址。本地主机 IP 地址不受此规则限制。

网域
  • 主机 TLD (顶级域名) 必须在公共后缀列表中。
  • 主机域名不能为 “googleusercontent.com”
  • JavaScript 来源不得包含使用网址缩短工具的网域(例如 goo.gl) 除非应用拥有该网域
  • 用户信息

    JavaScript 来源不能包含 userinfo 子组件。

    路径

    JavaScript 来源不能包含路径组件。

    查询

    JavaScript 来源不能包含查询组件。

    fragment

    JavaScript 来源不能包含 fragment 组件。

    角色 JavaScript 来源不得包含某些字符,包括:
    • 通配符 ('*')
    • 不可打印的 ASCII 字符
    • 百分比编码无效(不遵循网址编码的任何百分比编码) 后跟两个十六进制数字的形式)
    • Null 字符(经过编码的 NULL 字符,例如%00, %C0%80)

    增量授权

    在 OAuth 2.0 协议中,您的应用会请求授权,以访问资源, 由范围标识。请求授权被视为一种最佳用户体验做法 适时获取所需资源为此,Google 的授权服务器 支持增量授权。借助此功能,您可以根据需要请求范围, 如果用户为新范围授予权限,则返回一个授权代码,而该代码可能是 交换包含用户已授予项目的所有范围的令牌。

    例如,一款让用户对音乐曲目进行采样并创建混音的应用可能需要很少的 可能只不过是登录者的姓名而已。不过, 保存已完成的合辑需要访问其 Google 云端硬盘。大多数人会发现它 当然了,只有在应用实际运行时 应用才被要求访问自己的 Google 云端硬盘时 需要它。

    在这种情况下,应用可能会在登录时请求 openidprofile 作用域执行基本登录,然后在稍后请求 https://www.googleapis.com/auth/drive.file 范围,以保存 组合

    以下规则适用于通过增量授权获取的访问令牌:

    • 该令牌可用于访问与已纳入 新的合并授权。
    • 当您将刷新令牌用于组合授权以获取访问令牌时, 访问令牌表示合并的授权,可用于 响应中包含 scope 值。
    • 合并授权包括用户向 API 项目授予的所有范围,甚至包括 如果授权来自不同的客户端,则会发生此错误。例如,如果用户向 将一个范围授予应用的桌面客户端,然后将另一个范围授予同一应用 应用,则合并的授权将同时包含这两个授权范围。
    • 如果您撤消了某个表示组合授权的令牌,就可以访问所有这些 同时撤消代表关联用户的授权范围。

    以下代码示例展示了如何向现有访问令牌添加范围。这种方法允许 而无需管理多个访问令牌。

    OAuth 2.0 端点

    如需向现有访问令牌添加范围,请包含 include_granted_scopes 参数(位于发送到 Google OAuth 2.0 服务器的请求中)。

    以下代码段演示了如何执行此操作。该代码段假定您已存储 浏览器的本地存储空间中您的访问令牌有效的范围。( 完整示例代码存储了一系列作用域,以便获取 在浏览器的本地属性中设置 oauth2-test-params.scope 属性即可 storage.)

    代码段将访问令牌有效的范围与您要使用的范围进行比较 特定查询。如果访问令牌未涵盖该范围,系统就会启动 OAuth 2.0 流程。 在这里,oauth2SignIn 函数与 第 2 步(稍后的完整 示例)。

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    撤消令牌

    在某些情况下,用户可能希望撤消授予应用的访问权限。用户可以撤消访问权限 通过访问 账号设置。请参阅 删除 第三方网站和应用的“网站或应用访问权限”部分有权访问您账号的应用 支持文档。

    应用也有可能以编程方式撤消授予其的访问权限。 如果用户退订、移除 或者应用所需的 API 资源发生了显著变化。也就是说, 移除流程的必要步骤可能包括 API 请求, 授予该应用的权限。

    OAuth 2.0 端点

    要以编程方式撤销令牌,您的应用会向 https://oauth2.googleapis.com/revoke,并以参数的形式添加令牌:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    令牌可以是访问令牌,也可以是刷新令牌。如果令牌是访问令牌,且具有 相应的刷新令牌,相应刷新令牌也会被撤消。

    如果成功处理了吊销请求,那么响应的 HTTP 状态代码就是 200。对于错误情况,系统会随同返回 HTTP 状态代码 400 以及错误代码。

    以下 JavaScript 代码段展示了如何在不使用 适用于 JavaScript 的 Google API 客户端库。由于用于撤消的 Google OAuth 2.0 端点 令牌不支持跨源资源共享 (CORS),那么代码会创建一个表单并提交 将表单发送到端点,而不是使用 XMLHttpRequest() 方法发布 请求。

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }