用户认证

网络认证协议利用 HTTP 特性,但是 Chrome 应用在应用容器内运行,不通过 HTTP 加载,也不能执行重定向或者设置 Cookie。

使用 Chrome 浏览器的认证 API 验证用户:getAuthToken 用于登录 Google 帐户的用户,launchWebAuthFlow 用于登录非 Google 帐户的用户。如果您的应用使用自己的服务器来验证用户,您需要使用后者。

API 示例: 想试试这些代码吗?请参见这些示例,特别是 identity 示例

工作方式

Chrome 应用的用户拥有一个与其配置文件相关联的 Google 账户,应用可以使用 getAuthToken API 为这些用户获取 OAuth2 令牌。

需要与非 Google 认证提供商进行认证的应用必须调用 launchWebAuthFlow。该方法使用浏览器弹出窗口显示提供商网页,并捕获特定 URL 匹配表达式的重定向。重定向 URL 将传递给应用,应用可以从 URL 中提取令牌。

Google 帐户认证

如下是您需要完成的五个步骤:

  1. 向您的清单文件中添加权限,并上传应用。
  2. 将已安装的 manifest.json 中的密钥复制到您原来的清单文件中,这样在开发过程中您的应用程序标识符会保持一致。
  3. 为您的 Chrome 应用获取 OAuth2 客户端标识符。
  4. 更新您的清单文件,包含客户端标识符与区域。
  5. 获取认证令牌。

添加权限并上传应用

您需要确保 "identity" 权限包含在您的清单文件中,然后您可以将您的应用上传至应用与扩展程序管理页面(参见发布)。

"permissions": [
  "identity"
]

把密钥复制到您的清单文件中

当您在 Google OAuth 控制台中注册您的应用时,您需要提供您的应用程序的标识符,在令牌请求中会检查该标识符,所以开发过程中拥有一个一致的应用程序标识符是很重要的。

为了使您的应用程序标识符保持一致,您需要把已安装的 manifest.json 中的密钥复制到您原来的清单文件中。这一任务做起来并不轻松,如下是具体步骤:

  1. 进入您的用户配置文件目录。在 Mac OS X 上的例子:~/Library/Application\ Support/Google/Chrome/Default/Extensions
  2. 列出已安装的应用与扩展程序,找出应用与扩展程序管理页面中您的应用的标识符,并在此目录中找到匹配的同一标识符。
  3. 进入已安装的应用目录(在应用标识符中还有一个版本),打开已安装的 manifest.json(pico 可以方便地打开文件)。
  4. 将已安装的 manifest.json 中的 "key" 复制并粘贴到您的应用原来的清单文件中。

获取您的 OAuth2 客户端标识符

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

  1. 使用上传应用至 Chrome 网上应用店的同一个 Google 帐户登录 Google API 控制台
  2. 展开左上角的下拉菜单并选择 Create... 菜单项,创建新的项目。
  3. 创建并命名后,进入“Services”导航菜单项,打开你的应用需要的 Google 服务。
  4. 进入“API Access”导航菜单项,并单击 Create an OAuth 2.0 client ID... 这一蓝色按钮。
  5. 输入请求的商标信息,选择 Installed application 的类型。
  6. 选择 Chrome Application 并输入您的应用标识符(在应用和扩展程序管理页面显示的标识符)。

警告: 如果这里的应用标识符不匹配您的应用标识符,当您的应用调用 getAuthToken() 时会产生错误。

更新您的清单文件,添加 OAuth2 客户端标识符和区域

您需要更新您的清单文件来包含客户端标识符与区域。如下是 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) {
  // 使用令牌。
});

用户交互

调用 getAuthToken 时,您可以传递一个标识(在以上例子中为 interactive: true),表示您希望该 API 以交互模式还是静默模式调用。如果您以交互模式调用 API,必要时会向用户显示登录和/或访问请求用户界面,如以下屏幕截图所示:

screenshot showing UI when an app uses the Identity API
     to authenticate a Google account

如果您以静默模式调用该 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) {
          // 该状态可能表示缓存的访问令牌无效,
          // 使用新的令牌再试一次。
          retry = false;
          chrome.identity.removeCachedAuthToken(
              { 'token': access_token },
              getTokenAndXhr);
          return;
        }

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

非 Google 帐户认证

如下是您需要完成的三个步骤:

  1. 在提供商注册。
  2. 添加您的应用需要访问的提供商资源的权限。
  3. 获取认证令牌

在提供商注册

您需要在提供商注册一个 OAuth2 客户端标识符,并将客户端标识符配置为一个网站。注册期间如果要输入重定向 URI,请使用这种形式的 URL:https://<扩展程序标识符>.chromiumapp.org/<此处可以是任意内容>

例如,如果您的应用标识符为 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<', 'interactive': true},
  function(redirect_url) { /* 从 redirect_url 提取令牌 */ });

<进行认证的 URL> 是从网站向提供商进行认证的任何 URL。例如,假设您正在与一个提供商进行 OAuth2 流程,以客户端标识符 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 浏览器会捕获它并执行应用的回调函数,传递完整的重定向 URL。应用应该从 URL 中提取令牌。

互动模式与静默模式

调用 launchWebAuthFlow 时,您可以传递一个标志(在以上例子中为 'interactive': true),表示您是否希望 API 以交互模式调用。如果您以交互模式调用 API,如果有必要的话,为了获取令牌将会向用户显示用户界面(登录用户界面和/或访问请求用户界面,或者任何提供商特定的相关用户界面)。

如果您以静默模式调用 API,只有当提供商不显示任何用户界面就能够提供令牌时才会返回令牌。例如当应用在启动时执行这一流程或者更一般地没有涉及到用户操作的情况下,这是很有用的。

我们建议的最佳做法是,当没有涉及到用户操作(例如用户单击您的应用中的登录按钮)时使用静默模式。注意我们并没有对用户操作有强制要求。