The Okta Auth JavaScript SDK builds on top of our Authentication API and OpenID Connect & OAuth 2.0 API to enable you to create a fully branded sign-in experience using JavaScript.
You can learn more on the Okta + JavaScript page in our documentation.
This library uses semantic versioning and follows Okta's library version policy.
️ ️ ️ ️ ️ ️ ️ ️ ️
️ ️ ️ ️ ️ ️ ️ ️ ️
✔️ The current stable major version series is: 7.x
Version | Status |
---|---|
7.x |
✔️ Stable |
6.x |
Retired |
5.x |
Retired |
4.x |
Retired |
3.x |
Retired |
2.x |
Retired |
1.x |
Retired |
0.x |
Retired |
The latest release can always be found on the releases page.
If you run into problems using the SDK, you can:
Users migrating from previous versions of this SDK should see Migrating Guide to learn what changes are necessary.
This SDK is known to work with current versions of Chrome, Firefox, and Safari on desktop and mobile.
Compatibility with IE 11 / Edge can be accomplished by adding polyfill/shims for the following objects:
️ crypto polyfills are unable to use the operating system as a source of good quality entropy used to generate pseudo-random numbers that are the key to good cryptography. As such we take the posture that crypto polyfills are less secure and we advise against using them.
This module provides an entrypoint that implements all required polyfills.
If you are using the JS on a web page from the browser, you can copy the node_modules/@okta/okta-auth-js/dist
contents to publicly hosted directory, and include a reference to the okta-auth-js.polyfill.js
file in a <script>
tag. It should be loaded before any other scripts which depend on the polyfill.
If you're using a bundler like Webpack or Browserify, you can simply import import or require @okta/okta-auth-js/polyfill
at or near the beginning of your application's code:
import '@okta/okta-auth-js/polyfill';
or
require('@okta/okta-auth-js/polyfill');
The built polyfill bundle is also available on our global CDN. Include the following script in your HTML file to load before any other scripts:
<script src="https://global.oktacdn.com/okta-auth-js/7.5.1/okta-auth-js.polyfill.js" type="text/javascript" integrity="sha384-EBFsuVdi4TGp/DwS7b+t+wA8zmWK10omkX05ZjJWQhzWuW31t7FWEGOnHQeIr8+L" crossorigin="anonymous"></script>
️ The version shown in this sample may be older than the current version. We recommend using the highest version available
Many browsers have started blocking cross-origin or "third party" cookies by default. Although most of the Okta APIs supported by this SDK do not rely upon cookies, there are a few methods which do. These methods will break if third party cookies are blocked:
If your application depends on any of these methods, you should try to either rewrite your application to avoid using these methods or communicate to your users that they must enable third party cookies. Okta engineers are currently working on a better long-term solution to this problem.
Installing the Authentication SDK is simple. You can include it in your project via our npm package, @okta/okta-auth-js.
You'll also need:
When creating a new Okta application, you can specify the application type. This SDK is designed to work with SPA
(Single-page Applications) or Web
applications. A SPA
application will perform all logic and authorization flows client-side. A Web
application will perform authorization flows on the server.
From the Okta Admin UI, click Applications
, then select your application. You can view and edit your Okta application's configuration under the application's General
tab.
A string which uniquely identifies your Okta application.
To sign users in, your application redirects the browser to an Okta-hosted sign-in page. Okta then redirects back to your application with information about the user. You can learn more about how this works on Okta-hosted flows.
You need to whitelist the login redirect URL in your Okta application settings.
After you sign users out of your app and out of Okta, you have to redirect users to a specific location in your application. You need to whitelist the post sign-out URL in your Okta application settings.
Using our npm module is a good choice if:
To install @okta/okta-auth-js:
# Run this command in your project root folder.
# yarn
yarn add @okta/okta-auth-js
# npm
npm install --save @okta/okta-auth-js
If you are using the JS on a web page from the browser, you can copy the node_modules/@okta/okta-auth-js/dist
contents to publicly hosted directory, and include a reference to the okta-auth-js.min.js
file in a <script>
tag.
The built library bundle is also available on our global CDN. Include the following script in your HTML file to load before your application script:
<script src="https://global.oktacdn.com/okta-auth-js/7.5.1/okta-auth-js.min.js" type="text/javascript" integrity="sha384-6epSwnIDkI5zFNEVNjEYy3A7aSZ+C7ehmEyG8zDJZfP9Bmnxc51TK8du+2me4pjb" crossorigin="anonymous"></script>
️ The version shown in this sample may be older than the current version. We recommend using the highest version available
Then you can create an instance of the OktaAuth
object, available globally.
const oktaAuth = new OktaAuth({
// config
})
However, if you're using a bundler like Webpack or Rollup you can simply import or require the module.
// ES module
import { OktaAuth } from '@okta/okta-auth-js'
const authClient = new OktaAuth(/* configOptions */)
// CommonJS
var OktaAuth = require('@okta/okta-auth-js').OktaAuth;
var authClient = new OktaAuth(/* configOptions */);
For an overview of the client's features and authentication flows, check out our developer docs. There, you will learn how to use the Auth SDK on a simple static page to:
️ The developer docs may be written for an earlier version of this library. See Migrating from previous versions.
You can also browse the full API reference documentation.
⌛ Async methods return a promise which will resolve on success. The promise may reject if an error occurs.
var config = {
issuer: 'https://{yourOktaDomain}/oauth2/default',
clientId: 'GHtf9iJdr60A9IYrR0jw',
redirectUri: 'https://acme.com/oauth2/callback/home',
};
var authClient = new OktaAuth(config);
By default, creating a new instance of OktaAuth
will not create any asynchronous side-effects. However, certain features such as token auto renew, token auto remove and cross-tab synchronization require OktaAuth
to be running as a service. This means timeouts are set in the background which will continue working until the service is stopped. To start the OktaAuth
service, simply call the start
method right after creation and before calling other methods like handleRedirect. To terminate all background processes, call stop
. See Service Configuration for more info.
var authClient = new OktaAuth(config);
await authClient.start(); // start the service
await authClient.stop(); // stop the service
Note: Starting the service will also call authStateManager.updateAuthState.
Type definitions are provided implicitly through the types
entry in package.json
. Types can also be referenced explicitly by importing them.
import {
OktaAuth,
OktaAuthOptions,
TokenManagerInterface,
AccessToken,
IDToken,
UserClaims,
TokenParams
} from '@okta/okta-auth-js';
const config: OktaAuthOptions = {
issuer: 'https://{yourOktaDomain}'
};
const authClient: OktaAuth = new OktaAuth(config);
const tokenManager: TokenManagerInterface = authClient.tokenManager;
const accessToken: AccessToken = await tokenManager.get('accessToken') as AccessToken;
const idToken: IDToken = await tokenManager.get('idToken') as IDToken;
const userInfo: UserClaims = await authClient.token.getUserInfo(accessToken, idToken);
if (!userInfo) {
const tokenParams: TokenParams = {
scopes: ['openid', 'email', 'custom_scope'],
};
authClient.token.getWithRedirect(tokenParams);
}
Typescript versions prior to 3.6 have no type definitions for WebAuthn.
Support for WebAuthn in IDX API was introduced in @okta/[email protected]
.
To solve this issue please install package @types/webappsec-credential-management
version ^0.5.1
.
Web and native clients can obtain tokens using the authorization_code
flow which uses a client secret stored in a secure location. (SPA applications should use the PKCE
flow which does not use a client secret) To use the authorization_code
flow, set responseType
to "code"
and pkce
to false
:
var config = {
// Required config
issuer: 'https://{yourOktaDomain}/oauth2/default',
clientId: 'GHtf9iJdr60A9IYrR0jw',
redirectUri: 'https://acme.com/oauth2/callback/home',
// Use authorization_code flow
responseType: 'code',
pkce: false
};
var authClient = new OktaAuth(config);
The PKCE OAuth flow will be used by default. This library supports PKCE for both browser and NodeJS applications. PKCE is widely supported by most modern browsers when running on an HTTPS connection. PKCE requires that the browser implements crypto.subtle
(also known as webcrypto
). Most modern browsers provide this when running in a secure context (on an HTTPS connection). PKCE also requires the TextEncoder object. This is available on all major browsers except IE 11 and Edge < v79. To add support, we recommend using a polyfill/shim such as text-encoding.
If the user's browser does not support PKCE, an exception will be thrown. You can test if a browser supports PKCE before construction with this static method:
OktaAuth.features.isPKCESupported()
️ We strongly discourage using the implicit flow. Use PKCE and/or client credentials if possible.
Implicit OAuth flow is available as an option if PKCE flow cannot be supported in your deployment. It is widely supported by most browsers, and can work over an insecure HTTP connection. Note that implicit flow is less secure than PKCE flow, even over HTTPS, since raw tokens are exposed in the browser's history. For this reason, we highly recommending using the PKCE flow if possible.
Implicit flow can be enabled by setting the pkce
option to false
var config = {
pkce: false,
// other config
issuer: 'https://{yourOktaDomain}/oauth2/default',
};
var authClient = new OktaAuth(config);
To sign a user in, your application must redirect the browser to the Okta-hosted sign-in page.
Note: Initial redirect to Okta-hosted sign-in page starts a transaction with a stateToken lifetime set to one hour.
After successful authentication, the browser is redirected back to your application along with information about the user. Depending on your preferences it is possible to use the following callback strategies.
Most applications will handle an OAuth callback using a special route/page, separate from the signin page. However some SPA applications have no routing logic and will want to handle everything in a single page.
async function main() {
// create OktaAuth instance
var config = {
issuer: 'https://{yourOktaDomain}/oauth2/default',
clientId: 'GHtf9iJdr60A9IYrR0jw',
redirectUri: 'https://acme.com/oauth2/callback/home',
};
authClient = new OktaAuth(config);
// Subscribe to authState change event.
authClient.authStateManager.subscribe(function(authState) {
// Logic based on authState is done here.
if (!authState.isAuthenticated) {
// render unathenticated view
return;
}
// Render authenticated view
});
// Handle callback
if (authClient.token.isLoginRedirect()) {
const { tokens } = await authClient.token.parseFromUrl(); // remember to "await" this async call
authClient.tokenManager.setTokens(tokens);
}
// normal app startup
authClient.start(); // will update auth state and call event listeners
}
According to the OAuth 2.0 spec the redirect URI "MUST NOT contain a fragment component": https://tools.ietf.org/html/rfc6749#section-3.1.2 When using a hash/fragment routing strategy and OAuth 2.0, the redirect callback will be the main / default route. The redirect callback flow will be very similar to handling the callback without routing. We recommend defining the logic that will parse redirect url at the very beginning of your app, before any other authorization checks.
Additionally, if using hash routing, we recommend using PKCE and responseMode "query" (this is the default for PKCE). With implicit flow, tokens in the hash could cause unpredictable results since hash routers may rewrite the fragment.
TokenManager
: tokenManager.setTokensReference: DPoP (Demonstrating Proof-of-Possession) - RFC9449
DPoP
must be enabled in your Okta application (Guide: Configure DPoP)https
is required. A secure context is required for WebCrypto.subtle
IndexedDB
(MDN, caniuse)const config = {
// other configurations
pkce: true, // required
dpop: true,
};
const authClient = new OktaAuth(config);
Reference: The DPoP Authentication Scheme (RFC9449)
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsIm...
async function dpopAuthenticatedFetch (url, options) {
const { method } = options;
const dpop = await authClient.getDPoPAuthorizationHeaders({ url, method });
// dpop = { Authorization: "DPoP token****", Dpop: "proof****" }
const headers = new Headers({...options.headers, ...dpop});
return fetch(url, {...options, headers });
}
use_dpop_nonce
Reference: Resource Server-Provided Nonce (RFC9449)
Resource servers can also choose to provide a nonce value to be included in DPoP proofs sent to them. They provide the nonce using the DPoP-Nonce header in the same way that authorization servers do...
HTTP/1.1 401 Unauthorized
WWW-Authenticate: DPoP error="use_dpop_nonce",
error_description="Resource server requires nonce in DPoP proof"
DPoP-Nonce: eyJ7S_zG.eyJH0-Z.HX4w-7v
async function dpopAuthenticatedFetch (url, options) {
// ...previous example...
const resp = await fetch(url, {...options, headers });
// resp = HTTP/1.1 401 Unauthorized...
if (!resp.ok) {
const nonce = authClient.parseUseDPoPNonceError(resp.headers);
if (nonce) {
const retryDpop = await authClient.getDPoPAuthorizationHeaders({ url, method, nonce });
const retryHeaders = new Headers({...options.headers, ...retryDpop});
return fetch(url, {...options, headers: retryHeaders });
}
}
return resp;
}
DPoP requires certain browser features. A user using a browser without the required features will unable to complete a request for tokens. It's recommended to verify browser support during application bootstrapping.
// App.tsx
useEffect(() => {
if (!authClient.features.isDPoPSupported()) {
// user will be unable to request tokens
navigate('/unsupported-error-page');
}
}, []);
DPoP requires the generation of a CryptoKeyPair
which needs to be persisted in storage. Methods like signOut()
or revokeAccessToken()
will clear the key pair, however users don't always explicitly logout. It's therefore good practice to clear storage before login to flush any orphaned key pairs generated from previously requested tokens.
async function login (options) {
await authClient.clearDPoPStorage(); // clear possibly orphaned key pairs
return authClient.signInWithRedirect(options);
}
Whether you are using this SDK to implement an OIDC flow or for communicating with the Authentication API, the only required configuration option is issuer
, which is the URL to an Okta Authorization Server
You may use the URL for your Okta organization as the issuer. This will apply a default authorization policy and issue tokens scoped at the organization level.
var config = {
issuer: 'https://{yourOktaDomain}'
};
var authClient = new OktaAuth(config);
Okta allows you to create multiple custom OAuth 2.0 authorization servers that you can use to protect your own resource servers. Within each authorization server you can define your own OAuth 2.0 scopes, claims, and access policies. Many organizations have a "default" authorization server.
var config = {
issuer: 'https://{yourOktaDomain}/oauth2/default'
};
var authClient = new OktaAuth(config);
You may also create and customize additional authorization servers.
var config = {
issuer: 'https://{yourOktaDomain}/oauth2/custom-auth-server-id'
};
var authClient = new OktaAuth(config);
These options can be included when instantiating Okta Auth JS (new OktaAuth(config)
).
issuer
️ This option is required
The URL for your Okta organization or an Okta authentication server. About the issuer
clientId
Client Id pre-registered with Okta for the OIDC authentication flow. Creating your Okta application
redirectUri
The url that is redirected to when using token.getWithRedirect
. This must be listed in your Okta application's Login redirect URIs. If no redirectUri
is provided, defaults to the current origin (window.location.origin
). Configuring your Okta application
postLogoutRedirectUri
Specify the url where the browser should be redirected after signOut. This url must be listed in your Okta application's Logout redirect URIs. If not specified, your application's origin (window.location.origin
) will be used. Configuring your Okta application |
scopes
Specify what information to make available in the returned id_token
or access_token
. For OIDC, you must include openid
as one of the scopes. Defaults to ['openid', 'email']
. For a list of available scopes, see Scopes and Claims
state
A client-provided string that will be passed to the server endpoint and returned in the OAuth response. The value can be used to validate the OAuth response and prevent cross-site request forgery (CSRF). Defaults to a random string.
pkce
Default value is true
which enables the PKCE OAuth Flow. To use the Implicit Flow or Authorization Code Flow, set pkce
to false
.
dpop
Default value is false
. Set to true
to enable DPoP
(Demonstrating Proof-of-Possession (RFC9449))
See Guide: Enabling DPoP
When requesting tokens using token.getWithRedirect values will be returned as parameters appended to the redirectUri.
In most cases you will not need to set a value for responseMode
. Defaults are set according to the OpenID Connect 1.0 specification.
For PKCE OAuth Flow), the authorization code will be in search query of the URL. Clients using the PKCE flow can opt to instead receive the authorization code in the hash fragment by setting the responseMode option to "fragment".
For Implicit OAuth Flow), tokens will be in the hash fragment of the URL. This cannot be changed.
responseType
Specify the response type for OIDC authentication when using the Implicit OAuth Flow. The default value is ['token', 'id_token']
which will request both an access token and ID token. If pkce
is true
, both the access and ID token will be requested and this option will be ignored. For web/native applications using the authorization_code
flow, this value should be set to "code"
and pkce
should be set to false
.
authorizeUrl
Specify a custom authorizeUrl to perform the OIDC flow. Defaults to the issuer plus "/v1/authorize".
userinfoUrl
Specify a custom userinfoUrl. Defaults to the issuer plus "/v1/userinfo".
tokenUrl
Specify a custom tokenUrl. Defaults to the issuer plus "/v1/token".
ignoreSignature
️ This option should be used only for browser support and testing purposes.
ID token signatures are validated by default when token.getWithoutPrompt
, token.getWithPopup
, token.getWithRedirect
, and token.verify
are called. To disable ID token signature validation for these methods, set this value to true
.
maxClockSkew
Defaults to 300 (five minutes). This is the maximum difference allowed between a client's clock and Okta's, in seconds, when validating tokens. Setting this to 0 is not recommended, because it increases the likelihood that valid tokens will fail validation.
ignoreLifetime
️ This option disables token lifetime validation, which can introduce security vulnerability issues. This option should be used for testing purpose. Please handle the error in your own app for production environment.
Token lifetimes are validated using the maxClockSkew. To override this and disable token lifetime validation, set this value to true
.
transformAuthState
Callback function. When updateAuthState is called a new authState object is produced. Providing a transformAuthState
function allows you to modify or replace this object before it is stored and emitted. A common use case is to change the meaning of isAuthenticated. By default, updateAuthState
will set authState.isAuthenticated
to true if unexpired tokens are available from tokenManager. This logic could be customized to also require a valid Okta SSO session:
const config = {
// other config
transformAuthState: async (oktaAuth, authState) => {
if (!authState.isAuthenticated) {
return authState;
}
// extra requirement: user must have valid Okta SSO session
const