OpenID Connect is an HTTP service based on the OAuth 2 framework. Its purpose is to allow an application developer (“Relying Party” or RP) to:
A variety of libraries, from Google and third parties, provide APIs for accessing this service, taking care of many of the implementation details, in many cases to support access to Google APIs. Examples include the Google APIs Client Library for Java.
This document describes the HTTP request flows that underly these libraries. While they are available for public use, developers are advised, if possible, to take advantage of a pre-written library and avoid the work of dealing with low-level network traffic. Authenticating users properly is important to their and your safety and security, and using well-debugged code written by others is generally a best practice.
Our intent is that this service implement the required features of the OpenID Connect “Basic” and “Implicit” flows. Any client which is designed to work with those features should interoperate with this service.
OpenID Connect is based on OAuth 2.0, and the documentation found in Using OAuth 2.0 to Access Google APIs applies. OpenID Connect adds several concepts using OAuth 2.0 extension mechanisms; the following are used by this Google service:
The Google OAuth 2.0 Playground is recommended for interactive exploration of this protocol.
Any application that wants to use this service must be registered at the Google Developer Console. You will need to create a Client ID for a Web Application; this will yield two strings, “Client ID” and “Client Secret”, which are used in accessing the service. It will also specify a “redirect URI”, used in obtaining tokens.
Registering the app also allows you to provide text and an image for branding purposes, to be presented to users when they are prompted to approve authentication with your app.
Authenticating a user involves two steps: Obtaining an Access Token and ID Token, and validating the ID Token. The process of obtaining tokens is a standard OAuth2 process, with two possible message flows:
Developers are referred to Using OAuth 2.0 to Access Google APIs for details on implementing these flows.
The first step is an HTTPS GET request. Note the use of HTTPS rather than HTTP in all the steps of this process; HTTP connections are refused. The base URI is “https://accounts.google.com/o/oauth2/auth”, and the following parameters are used:
This is the Client-ID string obtained when registering your app at the Developer Console.
The scope value must begin with the string “openid ” and then include either or both of “profile” and “email”. Thus, possible values are “openid email”, “openid profile”, “openid profile email” and “openid email profile”.
The presence of “email” requests that the ID Token include “email” and “email_verified” claims, and that these values be included in the information available at the Userinfo endpoint. The presence of “profile” requests that a package of personal information be provided at the Userinfo endpoint.
When the user is asked to approve the authorization, the selection of scopes will affect the description he or she sees of what information will be made available to your application.
Determines where the response is sent. The value of this parameter must exactly match one of the values registered in the Developer Console (including the http or https schemes, case, and trailing '/').
state (optional, but strongly recommended)
This is an opaque string that you can supply, which is round-tripped in the protocol; that is to say, it is returned as a URI parameter in the Basic flow, and in the URI #fragment in the Implicit flow. This may be useful to applications in correlating requests and responses. Since it is possible to guess your redirect_uri, using a state value can increase your assurance that an incoming connection to it is the result of an authorization request. If you encode the hash of some client state (e.g., a cookie) in this state variable you additionally ensure that the request and response originated in the same browser (by validating the hash when processing the auth response) for protection against some attacks, such as cross-site request forgery.
A space-delimited list of string values that specifies whether the Authorization Server prompts the user for reauthentication and consent. The possible values are:
The Authorization Server will not display any authentication or consent pages; it will return an error if the user is not already authenticated and has not pre-configured consent for the requested scopes. This can be used as a method to check for existing authentication and/or consent.
The Authorization Server will prompt the user for consent before returning information to the Client.
The Authorization Server will prompt the user to select a user account. This allows a user who has multiple accounts at the Authorization Server to select amongst the multiple accounts that they may have current sessions for.
An ASCII string value that specifies how the Authorization Server displays the authentication and consent user interface pages. The following values are specified, and accepted by the Google servers, but do not have any effect on its behavior: “page”, “popup”, “touch”, and “wap”.
When the RP knows which which user it is trying to authenticate, it may provide this parameter as a hint to the Authentication Server. The value can be either an email address or user_id string.
The allowed values are “offline” and “online”. The effect is documented in Offline Access; if an Access Token is being requested, the client will not receive a Refresh Token unless “offline” is specified.
Here is an example of a complete OpenID Connect Authorization URI, with line-breaks inserted for readability after the “?” and each of the “&” parameter separators:
Before you can use the information in ID Token, or rely on it as an assertion that the user has authenticated, you must validate it. Validation comprises two steps:
The second step is just a string comparison. The first is a little more complex, and there are two strategies for accomplishing it:
Since Google changes its public keys only infrequently (on the order of once per day), you can cache them and, in the vast majority of cases, perform local validation much more efficiently than by using the TokenInfo endpoint. This requires retrieving and parsing certificates, and making the appropriate crypto calls to check the signature. Fortunately, there are well-debugged libraries available in a wide variety of languages to accomplish this.
Java programmers can use the open-source GoogleIDToken and GoogleIDTokenVerifer classes. For Rubyists using the Google API Library there’s Google::APIClient#verify_id_token! and if you don’t need the whole library, there’s a “google-id-token” gem which provides GoogleIDToken::Validator#check.
These libraries normally validate the token and return its parsed payload (if valid) in one step.
An ID Token contains a set of name/value pairs called “claims”. Here’s an example, formatted for readability:
The fields used by Google are:
The Issuer Identifier for the Issuer of the response.
If the ID Token is issued with an Access Token in an Implicit flow, this is required. The value is produced by base64url encoding the leftmost half of the hash created by hashing the access_token with the SHA-2 family hash algorithm of the same length as the hash used in the alg parameter of the JWS header. For instance, if the alg is HS256, hash access_token with SHA-256, then take the leftmost 128 bits and base64url encode them.
True if the user's e-mail address has been verified; otherwise false.
An identifier for the user, unique among all Google accounts and never reused. A Google account can have multiple emails at different points in time, but this user_id is never changed. You should use this within your application as the unique-identifier key for the user.
The user’s email address. This may not be unique and is not suitable for use as a primary key. Provided only if your scope included the string “email”.
Identifies the audience that this ID Token is intended for. It must be the OAuth 2.0 Client ID of your application.
An integer giving the time the ID Token was issued, in seconds since the beginning of 1970, UTC.
An integer giving the time the ID Token expires, in seconds since the beginning of 1970, UTC.
If your scope included the value “profile”, you may dereference the URI “https://www.googleapis.com/oauth2/v3/userinfo” to retrieve a package of information, encoded in JSON, about the user. You will need to use the Access Token (not ID Token) you received in the OAuth 2.0 authentication flow. It may be used either in a URI parameter or HTTP header, in the standard OAuth 2.0 fashion.
Different users may choose to supply or withhold certain of these fields. The user’s email address will be included only if your scope also included the value “email”.
The values in a typical Google profile might include “sub”, “email”, “email_verified”, “name”, “given_name”, “family_name”, “picture”, “gender”, “birthdate”, and “locale”. These are fairly self-explanatory, but there are a couple of things to watch out for.