At my talk at Over The Air 2013 this weekend in the wonderful Bletchley Park, one thing that surprised some people was the fact that Google has a OAuth 2.0 option for low capability devices. This is one of the big benefits of using Google as an IDP - it allows you to take advantage off all the work that the identity and security teams do in areas like 2-factor auth, data management, and access for all sorts of different environments.
The devices setup is really for cases where you want to allow a user to sign in to something that doesn’t have a great control setup - for example a TV or a wifi-enabled toaster. With it, the user only needs to indicate that they want to sign in, but they actually authenticate in a web browser on a regular PC or their mobile device.
You can take a look at how it works below. This iframe is representing a device that you might want to sign in to, and as soon as you click the Sign In button below, it’ll try to sign in and give you a code. You’ll need to enter the code into the device log in page at google.com/device, and approve the permissions. Then, the iframe should sign-in automatically.
This is the flow we’re going through:
On the device, we first request a device sign-in with the scopes we want to access, and a client ID to identify the project. Note that the client ID must have been created in the API console as for devices. You can’t use the same client ID as for a site or a mobile app, though they can of course be in the same project.
Making the call looks like this (in PHP, the natural language of wifi enabled toasters):
In the response we get a code for the device, a code for the user, and an interval (in seconds) that we can poll with to see whether the user has granted us permission. As you can see, the device code looks much like the code we’d get for a regular OAuth 2.0 flow, while the user code is a bit simpler!
{ "device_code" : "4/pH76g9gRK_r0_M8nFBp8ru0DikyU", "user_code" : "tgm224xy", "verification_url" : "http://www.google.com/device", "expires_in" : 1800, "interval" : 5 }
At this point we need to display the user_code to the user, and we can set up a loop to check for the token. The check is to the regular OAuth2 token endpoint, the same we’d use for a code or refresh token based call to get an access token. In the little app above there is a loop in Javascript to actually do the polling, but the check is made from the server side. This is because the client secret is needed, which naturally has to be kept on the server only. We have the sign-in button in the example above to avoid spamming the auth servers with this code check, as there really is no user interaction needed with the device.
This isn’t very much different from a regular code exchange, other than the different grant_type. In the demo we just parse the response, extract the token, and retrieve the user’s public Google+ profile to get their name. The response we get back includes the access token and a refresh token, so we wouldn’t have to ask the user to sign-in again after an hour. In the example app we just throw the credentials away.
At this point, we can call APIs and do all of the stuff that we need in order to enable printing your recent Google+ posts onto toast, or some other eminently Kickstarterable reason. Mainly though, we have an identity which can be shared with a signed-in user in a web or mobile app, meaning it’s easier to create a good experience for a user from app to device and vice versa.