Question

I have a Google Chrome extension with an external user system (username/email/sessionId), that people can log into using their self-chosen credentials (over SSL). I would like to change this to using Google OpenID login like this:

  1. User clicks "Log in via Google":
  2. Extension performs a checkid_immediate* login request:
    • If checkid_immediate login fails:
      1. The extension will opens a new tab with the specified parameters for checkid_setup** login (and email fetch).
      2. User selects accounts and approves my service.
      3. On my return page I save the OpenID identity and email in my database.
      4. I close the tab via Javascript.
    • Else checkid_immediate is successfull and an OpenID identity is returned:
      1. I determine which user by looking for the OpenID identity in my database.
  3. I log in the user and set up sessionId as usual.

As far as I have understood x-has-session will allow me to fetch the OpenID of the currently logged in user (if they have previously allowed my service to use their login), but the response is always openid_mode=setup_needed.

Using my own account for testing I am able to authorize using the new tab checkid_setup method and then get a successful response from the checkid_immediate XmlHttpRequest. This is, however, only possible when I insert my obtained OpenID from Google in the openid.claimed_id and openid.identity parameters.

The request is successfull regardless of the openid.identity and openid.ui.mode parameters.

Have I completely misunderstood what I can do with x-has-session?

If yes, is the only way to perform my checkid_immediate request from my extension (without opening it in a new tab) to do it via the OpenID identifier I obtained at the time of running the checkid_setup request?


*checkid_immediate request parameters (sent as a POST request using XMLHttpRequest):

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"
};

At the openid.return_to URL all I do is echo json_encode($_REQUEST) (only GET/POST vars, cookies not included) which is fetched as the response in my XmlHttpRequest.


*checkid_setup request parameters (opened in new tab):

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"
};
Was it helpful?

Solution

Ok, so I finally figured out why my test have been acting up weird (and why x-has-session seemed like it didn't do anything): If you are logged in with multipe accounts (which was the case for me) Google OpenID login works a bit differently.

Lets go through the differences (these results are obtained via my own testing, so they may not be 100% accurate - they are also assuming nothing else would triggers a setup_needed response from Google, such as switching openid.realm):


1: Immediate requests not specifying OpenID and not specifying x-has-session:

  • Not logged in: Google specifies the parameter openid_mode=setup_needed in the response.
  • Single session: If user has approved the service, Google specifies the parameter openid_mode=id_res otherwise openid_mode=setup_needed in the response.
  • Multiple sessions: Google specifies the parameter openid_mode=setup_needed in the response regardless of having approved the service or not.

2: Immediate requests not specifying OpenID, but specifying x-has-session:

  • Not logged in: Same as 1 (not logged in).
  • Single session: If user has approved the service, Google specifies the parameter openid_mode=id_res and ignores x-has-session otherwise openid_mode=setup_needed and openid_ext1_mode=x-has-session in the response.
  • Multiple sessions: Google specifies the parameter openid_mode=setup_needed in the response regardless of having approved the service or not.

3: Immediate requests specifying OpenID and not specifying x-has-session:

  • Not logged in: Same as 1 (not logged in).
  • Single session: Same as 1 (single session).
  • Multiple sessions: Same as single session.

4: Immediate requests specifying OpenID and x-has-session:

  • Not logged in: Same as 1 (not logged in).
  • Single session: Same as 2 (single session).
  • Multiple sessions: Same as single session.

In other words:

  • If using single session, immediate mode using x-has-session can either tell you if a Google user is logged in or return a successful response if user has already approved the service regardless of specifying their OpenID.
  • If using multiple sessions and specifying the OpenID the behavior is the same as single session.
  • If using multiple sessions without specifying the OpenID immediate mode always returns a failure response and x-has-session is not applicable.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top