oidc-client is a JavaScript library intended to run in browsers (and possibly Cordova style applications). It provides protocol support for OIDC and OAuth2, as well as management functions for user sessions and access tokens management.
If you are unfamiliar with OpenID Connect, then you should learn the protocol first. This library is designed as a spec-compliant protocol library.
All signin methods require at least these two steps:
- Make the browser load a URL on the authentication server
- Handle the redirect when the authentication server navigates the browser back to your redirect handler
The redirect will have a query string that this library can decode into user information
There are 3 variations of this process:
signinRedirect, where the library navigates the browser away from your page to the login form on the authentication serversigninSilent, where the library generates a hidden iframe into which the browser loads a URL on the authentication serversigningPopup, where the library opens a popup window with a URL on the authentication server
It may not be possible to distinguish which variation is being used from the query string generated by your authentication server. You should expect to need a separate redirect handler URL for each variation that you use.
In this variation the browser leaves your page entirely, then comes back to it after the user has successfully authenticated. This always works to get user information.
The URL that the user will be sent back to is the redirect_uri given when constructing the UserManager on which you call signinRedirect. If signinRedirect is given a parameter that has a state property, the value of that property will be reconstructed later on the User object.
The page that loads at redirect_uri can generate a User by reconstructing the UserManager and invoking signinRedirectCallback with the query string that came from the authentication server. The state property on the User object will be the state property of the parameter given to signinRedirect.
signinRedirectCallback causes the User object to be generated, but the promise it returns resolves to null, so the object must be retrieved by other means. If User generation fails, the promise will reject with a non-null error.
In this variation the library generates a hidden iframe into which the browser loads a URL on the authentication server, then redirects the iframe to your page. This only works to get user information when the authentication server is able to recognize an active session for the browser without any user interaction.
The URL that the iframe will be redirected to is the silent_redirect_uri given when constructing the UserManager on which you call signinSilent. If signinSilent is given a parameter that has a state property, the value of that property will be reconstructed later on the User object.
The page that loads at silent_redirect_uri cannot generate a User itself; the iframe is hidden and temporary, so that probably wouldn't be useful anyway. What it can do is trigger the generation of a User in the parent page by reconstructing the UserManager and invoking signinSilentCallback with the query string that came from the authentication server. The state property on the User object will be the state property of the parameter given to signinRedirect.
signinRedirect causes the User object to be generated, but the promise it returns resolves to null, so the object must be retrieved by other means. If User generation fails, the promise will reject with a non-null error.
There are two main classes that you might want to use depend on the level at with you use to use the library:
The UserManager class provides a higher level API for signing a user in, signing out, managing the user's claims returned from the OIDC provider, and managing an access token returned from the OIDC/OAuth2 provider. The UserManager is the primary feature of the library.
The OidcClient class provides the raw OIDC/OAuth2 protocol support for the authorization endpoint and the end session endpoint in the authorization server. It provides a bare-bones protocol implementation and is used by the UserManager class. Only use this class if you simply want protocol support without the additional management features of the UserManager class.
The remainder of this document will primarily focus on the UserManager.
The UserManager constructor requires a settings object as a parameter. The settings has these properties:
-
authority (string): The URL of the OIDC/OAuth2 provider.
-
client_id (string): Your client application's identifier as registered with the OIDC/OAuth2 provider.
-
redirect_uri (string): The redirect URI of your client application to receive a response from the OIDC/OAuth2 provider.
-
response_type (string, default:
'id_token'): The type of response desired from the OIDC/OAuth2 provider. -
scope (string, default:
'openid'): The scope being requested from the OIDC/OAuth2 provider.
The authority URL setting is used to make HTTP requests to discover more information about the OIDC/OAuth2 provider and populate a metadata property on the settings. If the server does not allow CORS on the metadata endpoint, then these additional settings can be manually configured. These values can be found on the metadata endpoint of the provider:
-
metadata property which contains:
-
issuer
-
authorization_endpoint
-
userinfo_endpoint
-
end_session_endpoint
-
jwks_uri
-
signingKeys (which is the
keysproperty of thejwks_uriendpoint)
-
prompt
-
display
-
max_age
-
ui_locales
-
login_hint
-
acr_values
-
clockSkew (number, default:
300): The window of time (in seconds) to allow the current time to deviate when validating id_token'siat,nbf, andexpvalues. -
loadUserInfo (boolean, default:
true): Flag to control if additional identity data is loaded from the user info endpoint in order to populate the user'sprofile. -
filterProtocolClaims (boolean, default:
true): Should OIDC protocol claims be removed fromprofile. -
post_logout_redirect_uri (string): The OIDC/OAuth2 post-logout redirect URI.
-
popup_redirect_uri (string): The URL for the page containing the call to
signinPopupCallbackto handle the callback from the OIDC/OAuth2 -
popupWindowFeatures (string, default:
'location=no,toolbar=no,width=500,height=500,left=100,top=100'): Thefeaturesparameter towindow.openfor the popup signin window. -
popupWindowTarget (string, default:
'_blank'): Thetargetparameter towindow.openfor the popup signin window. -
silent_redirect_uri (string): The URL for the page containing the code handling the silent renew.
-
automaticSilentRenew (boolean, default:
false): Flag to indicate if there should be an automatic attempt to renew the access token prior to its expiration. The attempt is made as a result of theaccessTokenExpiringevent being raised. -
silentRequestTimeout (number, default:
10000): Number of milliseconds to wait for the silent renew to return before assuming it has failed or timed out. -
accessTokenExpiringNotificationTime (number, default:
60): The number of seconds before an access token is to expire to raise theaccessTokenExpiringevent. -
userStore: (default: session storage): Storage object used to persist
Userfor currently authenticated user. E.g.userStore: new WebStorageStateStore({ store: window.localStorage }) -
monitorSession [1.1.0]: (default:
true): Will raise events for when user has performed a signout at the OP. -
checkSessionInterval: (default:
2000): Interval, in ms, to check the user's session. -
revokeAccessTokenOnSignout [1.2.1] (default:
false): Will invoke the revocation endpoint on signout if there is an access token for the user. -
includeIdTokenInSilentRenew [1.4.0] (default:
true): Flag to control ifid_tokenis included asid_token_hintin silent renew calls. -
staleStateAge (default:
300): Number (in seconds) indicating the age of state entries in storage for authorize requests that are considered abandoned and thus can be cleaned up.
Since the methods that trigger generation of a User object do not return that object (or a promise that resolves to that object, the generated User object must be retrieved by one of these means
-
The
getUsermethod onUserManagerreturns a promise that resolves to aUserobject. This can be done any time after generation, and must be done again if otherUserobjects are generated later. IfgetUseris called before generation, it may resolve to a staleUserwith invalid tokens. -
The
events.addUserLoadedmethod onUserManagertakes a callback function as a parameter, and thereafter whenever aUseris generated the callback will be invoked with thatUseras a parameter. This can be done any time before generation, and does not need to be done again if otherUserobjects are generated later (the same callback will be invoked again).
The library makes some attempt to save user information where it can be reloaded without making network requests. If getUser is called before triggering generation it might return a stale User with expired access tokens. If you get a User from getUser before triggering generation, do not assume the access tokens are valid. There are at least 2 ways to ensure that you don't use an expired User:
-
Check the
expiredandexpires_inproperties on theUserobject. These can tell you if the user has expired, but cannot tell you if the user has logged out in another tab and thereby invalidated the tokens. -
Just do a
signinSilentbefore you even think about callinggetUser. If it resolves, theUseryou get immediately after is valid; if it rejects you need to do an interactive login e.g. withsigninRedirect.
The querySessionStatus method on UserManager may be able to give complete status information, but it performs a callback to silent_redirect_uri that has a very different query than signinSilent.
-
getUser: Returns promise to load the
Userobject for the currently authenticated user. -
removeUser: Returns promise to remove from any storage the currently authenticated user.
-
signinRedirect: Returns promise to trigger a redirect of the current window to the authorization endpoint.
-
signinRedirectCallback: Returns promise to process response from the authorization endpoint. The result of the promise is the authenticated
User. -
signinSilent: Returns promise to trigger a silent request (via an iframe) to the authorization endpoint. The result of the promise is the authenticated
User. -
signinSilentCallback: Returns promise to notify the parent window of response from the authorization endpoint.
-
signinPopup: Returns promise to trigger a request (via a popup window) to the authorization endpoint. The result of the promise is the authenticated
User. -
signinPopupCallback: Returns promise to notify the opening window of response from the authorization endpoint.
-
signoutRedirect: Returns promise to trigger a redirect of the current window to the end session endpoint.
-
signoutRedirectCallback: Returns promise to process response from the end session endpoint.
-
signoutPopup [1.4.0]: Returns promise to trigger a redirect of a popup window window to the end session endpoint.
-
signoutPopupCallback [1.4.0]: Returns promise to process response from the end session endpoint from a popup window.
-
querySessionStatus [1.1.0]: Returns promise to query OP for user's current signin status. Returns object with session_state and subject identifier.
-
startSilentRenew [1.4.0]: Enables silent renew for the
UserManager. -
stopSilentRenew [1.4.0]: Disables silent renew for the
UserManager. -
clearStaleState: Removes stale state entries in storage for incomplete authorize requests.
-
settings: Returns the settings used to configure the
UserManager. -
events: Returns an object used to register for events raised by the
UserManager. -
metadataService: Returns an object used to access the metadata configuration of the OIDC provider.
The UserManager will raise various events about the user's session:
-
userLoaded: Raised when a user session has been established (or re-established).
-
userUnloaded: Raised when a user session has been terminated.
-
accessTokenExpiring: Raised prior to the access token expiring.
-
accessTokenExpired: Raised after the access token has expired.
-
silentRenewError: Raised when the automatic silent renew has failed.
-
userSignedOut [1.1.0]: Raised when the user's sign-in status at the OP has changed.
To register for the events, there is an events property on the UserManager with addXxx and removeXxx APIs to add/remove callbacks for the events. An example:
var mgr = new UserManager();
mgr.events.addAccessTokenExpiring(function(){
console.log("token expiring...");
});
The User type is returned from the UserManager's getUser API. It contains these properties:
-
id_token: The id_token returned from the OIDC provider.
-
profile: The claims represented by a combination of the
id_tokenand the user info endpoint. -
session_state: The session state value returned from the OIDC provider.
-
access_token: The access token returned from the OIDC provider.
-
scope: The scope returned from the OIDC provider.
-
expires_at: The expires at returned from the OIDC provider.
-
expires_in: Calculated number of seconds the access token has remaining.
-
expired: Calculated value indicating if the access token is expired.
-
scopes: Array representing the parsed values from the
scope.
The oidc-client-js library supports logging. You can set a logger by assigning Oidc.Log.logger to anything that supports a info, warn, and error methods that accept a params array. By default, no logger is configured.
The console object in the browser supports these, so a common way to easily enable logging in the browser is to simply add this code:
Oidc.Log.logger = console;
Also, logging has levels so you can control the verbosity by setting the Oidc.Log.level to one of Oidc.Log.NONE, Oidc.Log.ERROR, Oidc.Log.WARN, or Oidc.Log.INFO. The default is Oidc.Log.INFO.
Your callback URLs must be specified in the authentication server configuration, or the authentication server will not redirect to them.
Some authentication servers take your callback URL and append a query string that starts with "&" without including a "?" anywhere, which generates non-compliant URLs. If your callback URLs already have a query in them, appending a query that starts with "&" results in a compliant URL.
signinRedirectCallback etc can accept the entire URI in window.location.href; it isn't necessary to extract the query string first, and they will find the information in a non-compliant URL which is missing the "?"
automaticSilentRenew amounts to a periodic signinSilent. If a callback has been given to events.addUserLoaded, it is invoked when renewal succeeds.