该页面翻译自 Google Chrome Extensions 与 Google Chrome Apps。除非特别说明,该页面的内容遵循 Creative Commons Attribution 3.0 License,代码示例遵循 BSD License。
网络认证协议利用 HTTP 特性,但是 Chrome 应用在应用容器内运行,不通过 HTTP 加载,也不能执行重定向或者设置 Cookie。
使用 Chrome 浏览器的认证 API
验证用户:getAuthToken
用于登录 Google
帐户的用户,launchWebAuthFlow
用于登录非 Google
帐户的用户。如果您的应用使用自己的服务器来验证用户,您需要使用后者。
API 示例: 想试试这些代码吗?请参见 identity 示例。
Chrome 应用的用户拥有一个与其配置文件相关联的 Google
账户,应用可以使用 getAuthToken
API 为这些用户获取 OAuth2 令牌。
需要与非 Google 认证提供商进行认证的应用必须调用
launchWebAuthFlow
。该方法使用浏览器弹出窗口显示提供商网页,并捕获特定
URL 匹配表达式的重定向。重定向 URL 将传递给应用,应用可以从 URL 中提取令牌。
如下是您需要完成的五个步骤:
manifest.json
中的密钥复制到您原来的清单文件中,这样在开发过程中您的应用程序标识符会保持一致。
您需要确保 "identity" 权限包含在您的清单文件中,然后您可以将您的应用上传至应用与扩展程序管理页面(参见发布)。
"permissions": [ "identity" ]
当您在 Google OAuth 控制台中注册您的应用时,您需要提供您的应用程序的标识符,在令牌请求中会检查该标识符,所以开发过程中拥有一个一致的应用程序标识符是很重要的。
为了使您的应用程序标识符保持一致,您需要把已安装的
manifest.json
中的密钥复制到您原来的清单文件中。这一任务做起来并不轻松,如下是具体步骤:
~/Library/Application\ Support/Google/Chrome/Default/Extensions
manifest.json
(pico 可以方便地打开文件)。
manifest.json
中的 "key"
复制并粘贴到您的应用原来的清单文件中。
您需要在 Google API 控制台中注册您的应用,获取客户端标识符:
警告: 如果这里的应用标识符不匹配您的应用标识符,当您的应用调用 getAuthToken() 时会产生错误。
您需要更新您的清单文件来包含客户端标识符与区域。如下是 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,必要时会向用户显示登录和/或访问请求用户界面,如以下屏幕截图所示:
如果您以静默模式调用该 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); } }); } }
如下是您需要完成的三个步骤:
您需要在提供商注册一个
OAuth2 客户端标识符,并将客户端标识符配置为一个网站。注册期间如果要输入重定向
URI,请使用这种形式的
URL:https://<扩展程序标识符>.chromiumapp.org/<此处可以是任意内容>
例如,如果您的应用标识符为
abcdefghijklmnopqrstuvwxyzabcdef
,并且您希望路径为
provider_cb
,为了与其他提供商的重定向 URI
区分,您应该使用:https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb
为了向 Google API 端点发出跨来源 XHR,您需要在权限中将这些匹配表达式加入白名单:
"permissions": [ ... "https://docs.google.com/feeds/", "https://docs.googleusercontent.com/", "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,只有当提供商不显示任何用户界面就能够提供令牌时才会返回令牌。例如当应用在启动时执行这一流程或者更一般地没有涉及到用户操作的情况下,这是很有用的。
我们建议的最佳做法是,当没有涉及到用户操作(例如用户单击您的应用中的登录按钮)时使用静默模式。注意我们并没有对用户操作有强制要求。