3

我有一个带有外部用户系统(用户名/电子邮件/sessionId)的 Google Chrome 扩展程序,人们可以使用他们自己选择的凭据(通过 SSL)登录。我想将其更改为使用 Google OpenID 登录,如下所示:

  1. 用户点击“通过 Google 登录”:
  2. 扩展执行checkid_immediate* 登录请求:
    • 如果checkid_immediate登录失败:
      1. checkid_setup该扩展程序将打开一个新选项卡,其中包含** 登录(和电子邮件获取)的指定参数。
      2. 用户选择帐户并批准我的服务。
      3. 在我的返回页面上,我将 OpenID 身份和电子邮件保存在我的数据库中。
      4. 我通过 Javascript 关闭选项卡。
    • 否则checkid_immediate成功并返回 OpenID 身份:
      1. 我通过在我的数据库中查找 OpenID 身份来确定哪个用户。
  3. 我登录用户并sessionId照常设置。

据我了解x-has-session,将允许我获取当前登录用户的 OpenID(如果他们之前允许我的服务使用他们的登录名),但响应始终为openid_mode=setup_needed.

使用我自己的帐户进行测试,我能够使用新的选项卡checkid_setup方法进行授权,然后从checkid_immediateXmlHttpRequest 获得成功的响应。但是,只有当我在openid.claimed_idopenid.identity参数中插入从 Google 获得的 OpenID 时,这才有可能。

无论openid.identityopenid.ui.mode参数如何,请求都会成功。

我是否完全误解了我能做什么x-has-session

checkid_immediate如果是,是否是通过我在运行请求时获得的 OpenID 标识符从我的扩展程序(而不在新选项卡中打开它)执行我的请求的唯一方法checkid_setup


*checkid_immediate请求参数(使用 XMLHttpRequest 作为 POST 请求发送):

var endpoint = "https://www.google.com/accounts/o8/ud";
var openIdParameters = {
  "openid.ns": "http://specs.openid.net/auth/2.0",
  "openid.mode": "checkid_immediate",
  "openid.return_to": "http://example.com/googleAuth.php",
  "openid.realm": "http://example.com",
  "openid.claimed_id": "http://specs.openid.net/auth/2.0/identifier_select",
  "openid.identity": "http://specs.openid.net/auth/2.0/identifier_select",
  "openid.ns.ui": "http://specs.openid.net/extensions/ui/1.0",
  "openid.ui.mode": "x-has-session"
};

openid.return_toURL 处,我所做的只是回显json_encode($_REQUEST)(仅 GET/POST 变量,不包括 cookie),它在我的 XmlHttpRequest 中作为响应获取。


*checkid_setup请求参数(在新标签中打开):

var endpoint = "https://www.google.com/accounts/o8/ud";
var openIdParameters = {
  "openid.ns": "http://specs.openid.net/auth/2.0",
  "openid.mode": "checkid_setup",
  "openid.return_to": "http://example.com/googleAuth.php",
  "openid.realm": "http://example.com",
  "openid.claimed_id": "http://specs.openid.net/auth/2.0/identifier_select",
  "openid.identity": "http://specs.openid.net/auth/2.0/identifier_select",
  "openid.ns.ax": "http://openid.net/srv/ax/1.0",
  "openid.ax.mode": "fetch_request",
  "openid.ax.required": "email",
  "openid.ax.type.email": "http://axschema.org/contact/email"
};
4

1 回答 1

3

好的,所以我终于弄清楚了为什么我的测试表现得很奇怪(以及为什么x-has-session它似乎没有做任何事情):如果您使用多个帐户登录(对我来说就是这种情况),Google OpenID 登录有点工作不同。

让我们来看看差异(这些结果是通过我自己的测试获得的,因此它们可能不是 100% 准确 - 他们还假设没有其他任何东西会触发setup_neededGoogle 的响应,例如切换openid.realm):


1:未指定 OpenID 且未指定的即时请求x-has-session

  • 未登录: Googleopenid_mode=setup_needed在响应中指定参数。
  • 单次会话:如果用户已批准服务,Googleopenid_mode=id_resopenid_mode=setup_needed在响应中指定其他参数。
  • 多个会话:openid_mode=setup_needed无论是否批准服务,Google 都会在响应中指定参数。

2:立即请求不指定 OpenID,但指定x-has-session

  • 未登录:1相同(未登录)。
  • 单次会话:如果用户已批准服务,Google 会指定参数,否则在响应中openid_mode=id_res忽略。x-has-sessionopenid_mode=setup_neededopenid_ext1_mode=x-has-session
  • 多个会话:openid_mode=setup_needed无论是否批准服务,Google 都会在响应中指定参数。

3:立即请求指定 OpenID 而未指定x-has-session

  • 未登录:1相同(未登录)。
  • 单次会话:1(单次会话)。
  • 多个会话:与单个会话相同。

4:立即请求指定 OpenID 和x-has-session

  • 未登录:1相同(未登录)。
  • 单次会话:2(单次会话)。
  • 多个会话:与单个会话相同。

换句话说:

  • 如果使用单个会话,立即模式 usingx-has-session可以告诉您 Google 用户是否已登录,或者如果用户已经批准该服务,则无论指定其 OpenID是否都返回成功响应。
  • 如果使用多个会话并指定 OpenID,则行为与单个会话相同。
  • 如果使用多个会话而不指定 OpenID立即模式总是返回失败响应并且x-has-session不适用。
于 2012-12-06T12:37:52.357 回答