Web 身份验证协议利用 HTTP 功能,但 Chrome 应用在应用容器内运行;它们不会通过 HTTP 加载,也无法执行重定向或设置 Cookie。
使用 Chrome Identity API 对用户进行身份验证:getAuthToken
(针对已登录其 Google 账号的用户)和 launchWebAuthFlow
(针对已登录非 Google 账号的用户)。如果您的应用使用自己的服务器对用户进行身份验证,您将需要使用后者。
工作原理
Chrome 应用用户的个人资料会与 Google 账号相关联。应用可以使用 getAuthToken
API 为这些用户获取 OAuth2 令牌。
如需使用非 Google 身份提供程序执行身份验证,应用必须调用 launchWebAuthFlow
。此方法使用浏览器弹出式窗口显示提供商页面,并捕获重定向到特定网址格式的操作。重定向网址会传递给应用,应用会从网址中提取令牌。
Google 账号身份验证
您需要完成以下五个步骤:
- 向清单添加权限,然后上传应用。
- 将已安装的
manifest.json
中的密钥复制到源清单,以便您的应用 ID 在开发期间保持不变。 - 为您的 Chrome 应用获取 OAuth2 客户端 ID。
- 更新清单,以添加客户端 ID 和范围。
- 获取身份验证令牌。
添加权限并上传应用
您需要确保清单中包含身份权限。然后,您可以将应用上传到“应用和扩展程序管理”页面(请参阅发布)。
"permissions": [
"identity"
]
将密钥复制到清单中
在 Google OAuth 控制台中注册应用时,您需要提供应用的 ID,系统会在请求令牌期间检查该 ID。因此,在开发过程中使用一致的应用 ID 非常重要。
如需保持应用 ID 不变,您需要将已安装的 manifest.json
中的密钥复制到源清单。这项任务并不轻松,但具体步骤如下:
- 前往用户数据目录。在 MacO 上的示例:
~/Library/Application\ Support/Google/Chrome/Default/Extensions
- 列出已安装的应用和扩展程序,并将应用和扩展程序管理页面上的应用 ID 与此处的相同 ID 进行匹配。
- 前往已安装的应用目录(这将是应用 ID 中的版本)。打开已安装的
manifest.json
(使用 pico 可以快速打开该文件)。 - 复制已安装的
manifest.json
中的“键”,并将其粘贴到应用的源清单文件中。
获取 OAuth2 客户端 ID
您需要在 Google API 控制台中注册您的应用,以获取客户端 ID:
- 使用上传应用到 Chrome 应用商店时所用的 Google 账号登录 Google API 控制台。
- 展开左上角的下拉菜单,然后选择 Create... 菜单项,以创建新项目。
- 创建并命名后,前往“服务”导航菜单项,然后开启应用所需的所有 Google 服务。
- 前往“API 访问权限”导航菜单项,然后点击 Create an OAuth 2.0 client ID...(创建 OAuth 2.0 客户端 ID...)蓝色按钮。
- 输入要求提供的品牌信息,选择已安装的应用类型。
- 选择 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,系统会在必要时向用户显示登录和/或批准界面,如下面的屏幕截图所示:
如果您在静默模式下调用 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 个步骤:
- 向提供商注册。
- 为您的应用将要访问的提供程序资源添加权限。
- 获取身份验证令牌。
向提供商注册
您需要向提供方注册一个 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 才会返回令牌。例如,当应用在启动时执行流程时,或者在通常情况下没有涉及用户手势时,这非常有用。
我们建议的最佳实践是,在没有用户手势的情况下使用静默模式,在有用户手势(例如,用户点击了应用中的“登录”按钮)的情况下使用交互模式。请注意,我们不会强制执行手势要求。