token-handler-js-assistant
A helper library to help SPAs interact with the OAuth Agent in the Token Handler pattern.
Add to project
Add to your project using npm
npm install @curity/token-handler-js-assistant
How to use in your project
Import the Assistant into your project and initialize it using Configuration
object.
import {OAuthAgentClient} from "@curity/token-handler-js-assistant";
const client = new OAuthAgentClient({oauthAgentBaseUrl: 'https://api.example.com/oauthagent/example'})
The Configuration
object contains the following options:
oauthAgentBaseUrl
- a URL with path to the token handler application created in the Curity Identity Server (this URL ends with a token handler application ID
as defined in the Curity Identity Server configuration).
Using the initialized client
- Starting the user login
const response = await this.oauthAgentClient.startLogin({
extraAuthorizationParameters: {
scope: "openid profile",
login_hint: "username",
ui_locales: "en"
}
})
location.href = response.authorizationUrl
- Finishing the user login
const url = new URL(location.href)
const response = await client.endLogin({ searchParams: url.searchParams })
if (response.isLoggedIn) {
}
Note: The endLogin
function should only be called with authorization response parameters (when the authorization
server redirected user to the SPA after a successful user login). It's recommended to call onPageLoad()
instead
on every load of the SPA. This function makes a decision based the query string and either calls endLogin()
or session()
.
-
Handling page load
const sessionResponse = await client.onPageLoad(location.href)
if (sessionResponse.isLoggedIn) {
} else {
const response = await client.startLogin()
location.href = response.authorizationUrl
}
-
Refreshing tokens
await client.refresh()
-
Retrieving ID token claims
const sessionResponse = await client.session()
if (session.isLoggedIn === true) {
session.idTokenClaims?.sub
}
-
Logging out
const logoutResponse = await client.logout()
if (logoutResponse.logoutUrl) {
location.href = logoutResponse.logoutUrl;
}
-
Implementing preemptive refresh. session()
, refresh()
, endLogin()
and onPageLoad()
functions return accessTokenExpiresIn
if the Authorization Server includes expires_in
in token responses. This field contains number of seconds until an
access token that is in the proxy cookie expires. This value can be used to preemptively refresh the access token.
After calling onPageLoad()
and refresh()
:
if (response.accessTokenExpiresIn != null) {
const delay = Math.max(response.accessTokenExpiresIn - 2, 1)
setTimeout(
() => { client.refresh(); },
delay * 1000
);
}
Note: This is just a simplified example. The timeout has to be cleared properly (before every refresh, or before logout).
Cookie Security
SameSite=Strict
cookies are sent to APIs, which cannot be sent from malicious sites- to ensure that only precise whitelisted origins can send cookies to APIs, a
token-handler-version: 1
header is
sent by this library on every request to the OAuth Agent. In cross-origin deployments this ensures that a CORS pre-flight
request authorizes access. SPA developers may be required to send this header to token handler proxies as well (refer
to the token handler proxy documentation for details).