用户身份验证

Web 身份验证协议利用 HTTP 功能,但 Chrome 应用在应用容器内运行;它们不会通过 HTTP 加载,也无法执行重定向或设置 Cookie。

使用 Chrome Identity API 对用户进行身份验证:getAuthToken(针对已登录其 Google 账号的用户)和 launchWebAuthFlow(针对已登录非 Google 账号的用户)。如果您的应用使用自己的服务器对用户进行身份验证,您将需要使用后者。

工作原理

Chrome 应用用户的个人资料会与 Google 账号相关联。应用可以使用 getAuthToken API 为这些用户获取 OAuth2 令牌。

如需使用非 Google 身份提供程序执行身份验证,应用必须调用 launchWebAuthFlow。此方法使用浏览器弹出式窗口显示提供商页面,并捕获重定向到特定网址格式的操作。重定向网址会传递给应用,应用会从网址中提取令牌。

Google 账号身份验证

您需要完成以下五个步骤:

  1. 向清单添加权限,然后上传应用。
  2. 将已安装的 manifest.json 中的密钥复制到源清单,以便您的应用 ID 在开发期间保持不变。
  3. 为您的 Chrome 应用获取 OAuth2 客户端 ID。
  4. 更新清单,以添加客户端 ID 和范围。
  5. 获取身份验证令牌。

添加权限并上传应用

您需要确保清单中包含身份权限。然后,您可以将应用上传到“应用和扩展程序管理”页面(请参阅发布)。

"permissions": [
  "identity"
]

将密钥复制到清单中

在 Google OAuth 控制台中注册应用时,您需要提供应用的 ID,系统会在请求令牌期间检查该 ID。因此,在开发过程中使用一致的应用 ID 非常重要。

如需保持应用 ID 不变,您需要将已安装的 manifest.json 中的密钥复制到源清单。这项任务并不轻松,但具体步骤如下:

  1. 前往用户数据目录。在 MacO 上的示例: ~/Library/Application\ Support/Google/Chrome/Default/Extensions
  2. 列出已安装的应用和扩展程序,并将应用和扩展程序管理页面上的应用 ID 与此处的相同 ID 进行匹配。
  3. 前往已安装的应用目录(这将是应用 ID 中的版本)。打开已安装的 manifest.json(使用 pico 可以快速打开该文件)。
  4. 复制已安装的 manifest.json 中的“键”,并将其粘贴到应用的源清单文件中。

获取 OAuth2 客户端 ID

您需要在 Google API 控制台中注册您的应用,以获取客户端 ID:

  1. 使用上传应用到 Chrome 应用商店时所用的 Google 账号登录 Google API 控制台
  2. 展开左上角的下拉菜单,然后选择 Create... 菜单项,以创建新项目。
  3. 创建并命名后,前往“服务”导航菜单项,然后开启应用所需的所有 Google 服务。
  4. 前往“API 访问权限”导航菜单项,然后点击 Create an OAuth 2.0 client ID...(创建 OAuth 2.0 客户端 ID...)蓝色按钮。
  5. 输入要求提供的品牌信息,选择已安装的应用类型。
  6. 选择 Chrome 应用,然后输入您的应用 ID(与应用和扩展程序管理页面中显示的 ID 相同)。

使用 OAuth2 客户端 ID 和范围更新您的清单

您需要更新清单以包含客户端 ID 和范围。下面是 gdrive 示例的“oauth2”示例:

"oauth2": {
    "client_id": "665859454684.apps.googleusercontent.com",
    "scopes": [
      "https://www.googleapis.com/auth/drive"
    ]
  }

获取访问令牌

现在,您可以通过调用 identity.getAuthToken 来获取身份验证令牌了。

chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
  // Use the token.
});

用户互动

调用 getAuthToken 时,您可以传递一个标志(如上例中的 'interactive': true),指示您希望在交互模式下还是静默模式下调用 API。如果您在 Interactive 模式下调用该 API,系统会在必要时向用户显示登录和/或批准界面,如下面的屏幕截图所示:

屏幕截图:显示应用使用 Identity API 对 Google 账号进行身份验证时的界面

如果您在静默模式下调用 API,则只有在能够在不显示任何界面的情况下生成令牌时,API 才会返回令牌。例如,当应用在启动时执行流程时,或者在通常情况下涉及不到用户手势时,这非常有用。

我们建议的最佳实践是,在没有用户手势的情况下使用静默模式,在有用户手势(例如,用户点击了应用中的“登录”按钮)的情况下使用交互模式。请注意,我们不会强制执行任何手势要求。

缓存

Chrome 具有访问令牌的内存缓存,因此您可以随时调用 getAuthToken 来使用令牌。令牌过期由缓存自动处理。

您可以在 chrome://identity-internals 上查看令牌缓存的当前状态。

在某些情况下(例如当用户更改密码时),未过期的访问令牌会停止有效。使用该令牌的 API 调用将开始返回 HTTP 状态代码 401。如果您检测到这种情况,可以通过调用 identity.removeCachedAuthToken 从 Chrome 的缓存中移除无效令牌。

removeCachedAuthToken 用法示例:

// callback = function (error, httpStatus, responseText);
function authenticatedXhr(method, url, callback) {
  var retry = true;
  function getTokenAndXhr() {
    chrome.identity.getAuthToken({/* details */},
                                 function (access_token) {
      if (chrome.runtime.lastError) {
        callback(chrome.runtime.lastError);
        return;
      }

      var xhr = new XMLHttpRequest();
      xhr.open(method, url);
      xhr.setRequestHeader('Authorization',
                           'Bearer ' + access_token);

      xhr.onload = function () {
        if (this.status === 401 && retry) {
          // This status may indicate that the cached
          // access token was invalid. Retry once with
          // a fresh token.
          retry = false;
          chrome.identity.removeCachedAuthToken(
              { 'token': access_token },
              getTokenAndXhr);
          return;
        }

        callback(null, this.status, this.responseText);
      }
    });
  }
}

非 Google 账号身份验证

您需要完成以下 3 个步骤:

  1. 向提供商注册。
  2. 为您的应用将要访问的提供程序资源添加权限。
  3. 获取身份验证令牌。

向提供商注册

您需要向提供方注册一个 OAuth2 客户端 ID,并将该客户端 ID 配置为网站。对于要在注册期间输入的重定向 URI,请使用以下格式的网址:https://<extension-id>.chromiumapp.org/<anything-here>

例如,如果您的应用 ID 为 abcdefghijklmnopqrstuvwxyzabcdef,并且您希望将 provider_cb 用作路径,以便将其与其他提供方的重定向 URI 区分开来,则应使用:https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb

为提供程序添加权限

如需向提供方 API 端点发出跨源 XHR,您需要在权限中将适当的模式列入许可名单:

"permissions": [
  ...
  "https://www.website-of-provider-with-user-photos.com/photos/*"
]

获取令牌

如需获取令牌,请执行以下操作:

chrome.identity.launchWebAuthFlow(
  {'url': '<url-to-do-auth>', 'interactive': true},
  function(redirect_url) { /* Extract token from redirect_url */ });

<url-to-do-auth> 是用于从网站对提供方进行身份验证的任意网址。例如,假设您正在与提供方执行 OAuth2 流程,并已使用客户端 ID 123456789012345 注册了您的应用,并且您希望访问提供方网站上的用户照片:https://www.website-of-provider-with-user-photos.com/dialog/oauth?client_id=123456789012345& redirect_uri=https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb&response_type=token&scope=user_photos

提供程序将执行身份验证,并根据需要向用户显示登录和/或批准界面。然后,系统会重定向到 https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb#authToken=<auth-token>

Chrome 会捕获该事件,并使用完整的重定向网址调用应用的回调。应用应从网址中提取令牌。

交互模式与静默模式

调用 launchWebAuthFlow 时,您可以传递一个标志(如上例中的 'interactive': true),指示您是否希望在交互模式(也称为静默模式)下调用该 API。如果您在 Interactive 模式下调用 API,系统会根据需要向用户显示界面以获取令牌(登录界面和/或批准界面;或者任何提供方专用界面)。

如果您在静默模式下调用 API,则只有在提供程序能够在不显示任何界面的情况下提供令牌时,API 才会返回令牌。例如,当应用在启动时执行流程时,或者在通常情况下没有涉及用户手势时,这非常有用。

我们建议的最佳实践是,在没有用户手势的情况下使用静默模式,在有用户手势(例如,用户点击了应用中的“登录”按钮)的情况下使用交互模式。请注意,我们不会强制执行手势要求。