- Introduction
- Install
- Getting Started
- Try Out the Sample Apps
- Browser Compatibility
- APIs
- AuthProvider
- SecureRoute
- useAuthContext
- getBasicUserInfo
- signIn
- signOut
- httpRequest
- httpRequestAll
- requestCustomGrant
- revokeAccessToken
- getOIDCServiceEndpoints
- getDecodedIDToken
- getIDToken
- getAccessToken
- refreshAccessToken
- on
- isAuthenticated
- enableHttpHandler
- disableHttpHandler
- updateConfig
- getHttpClient
- Using the
form_postResponse Mode - Storage
- Models
- Develop
- Contribute
- License
Asgardeo Auth React SDK for JavaScript allows React applications to use OIDC or OAuth2 authentication in a simple and secure way. By using Asgardeo and the Asgardeo Auth React SDK, developers will be able to add identity management to their React applications fast and secure.
Install the library from the npm registry.
npm install --save @asgardeo/auth-react
Or simply load the SDK by importing the script into the header of your HTML file.
<script src="https://unpkg.com/@asgardeo/[email protected]/dist/asgardeo-react.production.min.js.js"></script>
<script>
var auth = AsgardeoAuth.AsgardeoSPAClient.getInstance();
</script>// The SDK provides a provider that can be used to carry out the authentication.
// The `AuthProvider` is a React context.
// `useAuthContext` is a React hook that provides you with authentication methods such as `signIn`.
import { AuthProvider, useAuthContext } from "@asgardeo/auth-react";
// The config data.
const config = {
signInRedirectURL: "https://localhost:5000/sign-in",
signOutRedirectURL: "https://localhost:5000/dashboard",
clientID: "client ID",
serverOrigin: "https://localhost:9443"
};
// Encapsulate your components with the `AuthProvider`.
export const MyApp = (): ReactElement => {
return (
<AuthProvider config={ config }>
<Dashboard />
</AuthProvider>
)
}
const Dashboard = (): ReactElement => {
const { signIn } = useAuthContext();
const [ signedIn, setSignedIn ] = useState(false);
const handleClick = (): void => {
signIn(() => {
setSignedIn(true);
});
}
return (
<div>
{ signedIn && <div>You have signed in!</div> }
<button onClick={handleClick}> Sign In </button>
</div>
);
}
}Before trying out the sample apps, you need to a create a service provider in the Identity Server.
-
So, navigate to
https://localhost:9443/carbon" and click onAddunderService Providers` in the left-hand menu panel. -
Enter
Sampleas the name of the app and click onRegister. -
Then, expand the
Inbound Authentication Configurationsection. Under that, expandOAuth/OpenID Connect Configurationsection and click onConfigure. -
Under
Allowed Grant Typesuncheck everything exceptCodeandRefresh Token. -
Enter the Callback URL(s). You can find the relevant callback URL(s) of each sample app in the Running the sample apps section.
-
Check
Allow authentication without the client secret. -
Click
Addat the bottom. -
Copy the
OAuth Client Key. -
Enable CORS for the client application by following this guide (https://is.docs.wso2.com/en/5.11.0/learn/cors/).
Build the apps by running the following command at the root directory.
npm run build
This is a React Context Provider that provides the session state that contains information such as the authenticated user's display name, email address, etc., and the methods that are required to implement authentication in the React app.
Like every other provider, the AuthProvider also encapsulates the components that would need the data provided by the provider.
The provider takes a prop called config that accepts a config object of type AuthClientConfig<Config>. This config object contains attributes that provide the configurations necessary for authentication. To learn more about what attributes the object takes, refer to the AuthClientConfig<Config> section.
export const MyApp = (): ReactElement => {
return (
<AuthProvider config={ config }>
<Dashboard />
</AuthProvider>
)
}The SDK also provides a component called SecureRoute that wraps the Route component provided by react-routerdom`. This allows you to secure your routes using the SDK. Only authenticated users will be taken to the route. The component let's you pass a callback function that would be fired if the user is not authenticated.
This component takes three props. The path and component props just relay the prop values directly to the Route component. The callback prop takes a callback function that is fired when an unauthenticated user access teh route. Developers can use this callback function to either to redirect the user to the login page of the app to call the signIn method.
<SecureRoute path={ "/secure-page" } component={ <SecureComponent /> } callback={ callback } />This is a React hook that returns the session state that contains information such as the email address of the authenticated user and the methods that are required for implementing authentication.
const { signIn } = useAuthContext();The object returned by the useAuthContext has a state attribute the value of which is an object of type AuthStateInterface. You can refer the link to know more about what data is contained by the state object.
In addition to the state object, the hook also returns the following methods.
getBasicUserInfo(): Promise<BasicUserInfo>;A Promise that resolves with BasicUserInfo.
This method returns a promise that resolves with the information about the authenticated user obtained from the id token as an object. To learn more what information this object contains, refer to the BasicUserInfo section.
auth.getBasicUserInfo().then((response) => {
// console.log(response);
}).catch((error) => {
// console.error(error);
});signIn(callback?: (response: BasicUserInfo) => void, config?: SignInConfig, authorizationCode?: string, sessionState?: string);-
callback?: (response:
BasicUserInfo) =>voidA callback function that fires when sign-in is successful. The callback function takes an object of typeBasicUserInfoas an argument. -
config?:
SignInConfig(optional) An object that contains attributes that allows you to configure sign in. TheforceInitattribute of this object, allows you to force a request to the.well-knownendpoint even if a request has previously been sent. You can also pass key-value pairs that you want to be appended as path parameters to the authorization URL to this object. To learn more, refer toSignInConfig. This object is needed only during the authorization-url-generation phase. -
authorizationCode?:
string(optional) ThesignInmethod can be passed the authorization code as an argument, which will be used to obtain the token during the token-request phase of the method. This allows developers to use different response modes such asform_post. To learn more about theform_postmethod refer to the Using theform_postresponse mode section. If you're using thequerymethod, then thesignInmethod automatically obtains the authorization code from the URL. -
sessionState?:
string(optional) ThesignInmethod can be passed the session state as an argument, which will be used to obtain the token during the token-request phase of the method. This allows developers to use different response modes such asform_post. To learn more about theform_postmethod refer to the Using theform_postresponse mode section. If you're using thequerymethod, then thesignInmethod automatically obtains the session state from the URL.
As the name implies, this method is used to sign-in users. This method will have to be called twice to implement the two phases of the authentication process. The first phase generates generates the authorization URl and takes the user to the single-sign-on page of the identity server, while second phase triggers the token request to complete the authentication process. So, this method should be called when initiating authentication and when the user is redirected back to the app after authentication themselves with the server.
The sign-in hook is used to fire a callback function after signing in is successful. Check the on() section for more information.
auth.signIn();signOut();This method ends the user session at the Identity Server and logs the user out.
The sign-out hook is used to fire a callback function after signing out is successful. Check the on() section for more information.
auth.signOut();httpRequest(config: `HttpRequestConfig`): Promise<HttpResponse>;- config:
HttpRequestConfigA config object with the settings necessary to send http requests. This object is similar to theAxiosRequestConfig.
A Promise that resolves with the response.
This method is used to send http requests to the Identity Server. The developer doesn't need to manually attach the access token since this method does it automatically.
If the storage type is set to sessionStorage or localStorage, the developer may choose to implement their own ways of sending http requests by obtaining the access token from the relevant storage medium and attaching it to the header. However, if the storage is set to webWorker, this is the ONLY way http requests can be sent.
This method accepts a config object which is of type AxiosRequestConfig. If you have used axios before, you can use the httpRequest in the exact same way.
For example, to get the user profile details after signing in, you can query the me endpoint as follows:
const auth = AsgardeoSPAClient.getInstance();
const requestConfig = {
headers: {
"Accept": "application/json",
"Content-Type": "application/scim+json"
},
method: "GET",
url: "https://localhost:9443/scim2/me"
};
return auth.httpRequest(requestConfig)
.then((response) => {
// console.log(response);
})
.catch((error) => {
// console.error(error);
});httpRequestAll(config[]: ): Promise<[]>;- config[]:
HttpRequestConfig[]An array config objects with the settings necessary to send http requests. This object is similar to theAxiosRequestConfig.
A Promise that resolves with the responses.
This method is used to send multiple http requests at the same time. This works similar to axios.all(). An array of config objects need to be passed as the argument and an array of responses will be returned in a Promise in the order in which the configs were passed.
auth.httpRequestAll(configs).then((responses) => {
response.forEach((response) => {
// console.log(response);
});
}).catch((error) => {
// console.error(error);
});requestCustomGrant(config: CustomGranConfig, callback?: (response: BasicUserInfo | HttpResponse<any>) => void): Promise<HttpResponse | BasicUserInfo>;- config:
CustomGrantConfigA config object to configure the custom-grant request. To learn more about the different attributes that can be used with config object, see theCustomGrantConfigsection. - callback?: (response:
BasicUserInfo|HttpResponse) => void A callback function that takes an object of typeBasicUserInfoorHttpResponse(depending on theconfig) as an argument and is fired when the request is successful.
A Promise that resolves either with the response or the BasicUserInfo.
This method allows developers to use custom grants provided by their Identity Servers. This method accepts an object that has the following attributes as the argument.
The custom-grant hook is used to fire a callback function after a custom grant request is successful. Check the on() section for more information.
const config = {
attachToken: false,
data: {
client_id: "{{clientID}}",
grant_type: "account_switch",
scope: "{{scope}}",
token: "{{token}}",
},
id: "account-switch",
returnResponse: true,
returnsSession: true,
signInRequired: true
}
auth.requestCustomGrant(config).then((response)=>{
console.log(response);
}).catch((error)=>{
console.error(error);
});revokeAccessToken();This method revokes the access token and clears the session information from the storage.
The end-user-session hook is used to fire a callback function after end user session is successful. Check the on() section for more information.
auth.revokeAccessToken();getOIDCServiceEndpoints(): Promise<OIDCEndpoints>A Promise that resolves with an object containing the endpoints. To learn more about what endpoints are returned, refer to the OIDCEndpoints section.
This method returns a promise that resolves with an object containing the OIDC endpoints obtained from the .well-known endpoint. The object contains the following attributes.
| Attribute | Description |
|---|---|
"authorize" |
The endpoint to which the authorization request should be sent. |
"jwks" |
The endpoint from which JSON Web Key Set can be obtained. |
"oidcSessionIFrame" |
The URL of the page that should be loaded in an IFrame to get session information. |
"revoke" |
The endpoint to which the revoke-token request should be sent. |
"token" |
The endpoint to which the token request should be sent. |
"wellKnown" |
The well-known endpoint from which OpenID endpoints of the server can be obtained. |
auth.getOIDCServiceEndpoints().then((endpoints) => {
// console.log(endpoints);
}).error((error) => {
// console.error(error);
});getDecodedIDToken(): Promise<DecodedIDTokenPayload>A promise that returns with the DecodedIDTokenPayload object.
This method returns a promise that resolves with the decoded payload of the JWT ID token.
auth.getDecodedIDToken().then((idToken) => {
// console.log(idToken);
}).error((error) => {
// console.error(error);
});getIDToken(): Promise<string>idToken: Promise<string>
The id token.
This method returns the id token.
const idToken = await auth.getIDToken();getAccessToken(): Promise<string>;A Promise that resolves with the access token.
This returns a promise that resolves with the access token. The promise resolves successfully only if the storage type is set to a type other than webWorker. Otherwise an error is thrown.
auth.getAccessToken().then((token) => {
// console.log(token);
}).error((error) => {
// console.error(error);
});refreshAccessToken(): Promise<BasicUserInfo>;A Promise that resolves with the BasicUserInfo object.
This refreshes the access token and stores the refreshed session information in either the session or local storage as per your configuration. Note that this method cannot be used when the storage type is set to webWorker since the web worker automatically refreshes the token and there is no need for the developer to do it.
This method also returns a Promise that resolves with an object containing the attributes mentioned in the table below.
| Attribute | Description |
|---|---|
"accessToken" |
The new access token |
"expiresIn" |
The expiry time in seconds |
"idToken" |
The ID token |
"refreshToken" |
The refresh token |
"scope" |
The scope of the access token |
"tokenType" |
The type of the token. E.g.: Bearer |
auth.refreshToken().then((response)=>{
// console.log(response);
}).catch((error)=>{
// console.error(error);
});on(hook: string, callback: () => void, id?: string): void- hook:
stringThe name of the hook. - callback:
() => voidThe callback function that should be fired. - id?:
stringAn id for the method. This is required only when the hook type iscustom-grant.
The on method is used to hook callback functions to authentication methods. The method accepts a hook name and a callback function as the only arguments except when the hook name is "custom-grant", in which case the id of the custom grant should be passed as the third argument. The following hooks are available.
If you are using TypeScript, you may want to use the Hooks enum that consists of the following string literals instead of directly inputting the string value.
| Hook | Method to which the callback function is attached | Returned Response |
|---|---|---|
"sign-in" |
signIn() |
The user information. See getUserInfo()'s return type for more details. |
"sign-out" |
signOut() |
|
"initialize" |
initialize() |
A boolean value indicating if the initialization was successful or not. |
"http-request-start" |
httpRequest() (Called before an http request is sent) |
|
"http-request-finish" |
httpRequest() (Called after an http request is sent and response is received.) |
|
"http-request-error" |
httpRequest() (Called when an http request returns an error) |
|
"http-request-success" |
httpRequest() (Called when an http requests returns a response successfully) |
|
"end-user-session" |
endUserSession() |
A boolean value indicating if the process was successful or not |
"custom-grant" |
customGrant() |
Returns the response from the custom grant request. |
When the user signs out, the user is taken to the identity server's logout page and then redirected back to the SPA on successful log out. Hence, developers should ensure that the "sign-out" hook is called when the page the user is redirected to loads.
auth.on("sign-in", () => {
//called after signing in.
});isAuthenticated(): booleanisAuth: boolean
A boolean value that indicates of the user is authenticated or not.
This method returns a boolean value indicating if the user is authenticated or not.
const isAuth = auth.isAuthenticated();enableHttpHandler(): Promise<Boolean>A Promise that resolves with a boolean value indicating if the call was successful.
This enables the callback functions attached to the http client. The callback functions are enabled by default. This needs to be called only if the disableHttpHandler method was called previously.
auth.enableHttpHandler();disableHttpHandler(): Promise<boolean>A Promise that resolves with a boolean value indicating if the call was successful.
This disables the callback functions attached to the http client.
auth.disableHttpHandler();updateConfig(config: Partial<AuthClientConfig<T>>): void- config:
AuthClientConfig<T>
The config object containing the attributes that can be used to configure the SDK. To learn more about the available attributes, refer to the AuthClientConfig>T> model.
This method can be used to update the configurations passed into the constructor of the AsgardeoAuthClient. Please note that every attribute in the config object passed as the argument here is optional. Use this method if you want to update certain attributes after instantiating the class.
auth.updateConfig({
signOutRedirectURL: "https://localhost:5000/sign-out"
});auth.getHttpClient(): `HttpClientInstance`An HttpClientInstance
This method returns the HttpClientInstance. This is the client that is used to send http requests internally.
const httpClient = auth.getHttpClient();When the responseMode is set to form_post, the authorization code is sent in the body of a POST request as opposed to in the URL. So, the Single Page Application should have a backend to receive the authorization code and send it back to the Single Page Application.
The backend can then inject the authorization code into a JavaSCript variable while rendering the webpage in the server side. But this results in the authorization code getting printed in the HTML of the page creating a threat vector.
To address this issue, we recommend storing the authorization code in a server session variable and providing the Single Page Application a separate API endpoint to request the authorization code. The server, when the request is received, can then respond with the authorization code from the server session.
You can refer to a sample implementation using JSP here.
Asgardeo allows the session information including the access token to be stored in three different places, namely,
- Session storage
- Local storage
- Web worker
- Browser memory
Of the four methods, storing the session information in the web worker is the safest method. This is because the web worker cannot be accessed by third-party libraries and data there cannot be stolen through XSS attacks. However, when using a web worker to store the session information, the httpRequest method has to be used to send http requests. This method will route the request through the web worker and the web worker will attach the access token to the request before sending it to the server.
auth.initialize(config);| Attribute | Type | Description |
|---|---|---|
allowedScopes |
string |
The scopes that are allowed for the user. |
displayName |
string |
The display name of the user. |
email |
string |
The email address of the user. |
isAuthenticated |
boolean |
Specifies if the user is authenticated or not. |
username |
string |
The username of the user. |
The AuthClientConfig<Config> interface extends the AuthClientConfig<T> interface provided by the Asgardeo JavaScript Auth SDK with the Config interface. This table lists the attributes that the AuthClientConfig<T> interface takes.
This table shows the extended attributes provided by the Config interface.
| Attribute | Required/Optional | Type | Default Value | Description |
|---|---|---|---|---|
storage |
Optional | "sessionStorage", "webWorker", "localStorage" |
"sessionStorage" |
The storage medium where the session information such as the access token should be stored. |
resourceServerURLs |
Required if the storage is set to webWorker |
string[] |
[] |
The URLs of the API endpoints. This is needed only if the storage method is set to webWorker. When API calls are made through the httpRequest or the httpRequestAll method, only the calls to the endpoints specified in the baseURL attribute will be allowed. Everything else will be denied. |
requestTimeout |
Optional | number |
60000 (seconds) | Specifies in seconds how long a request to the web worker should wait before being timed out. |
| Attribute | Required/Optional | Type | Default Value | Description |
| ---------------------------- | ----------------- | --------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| signInRedirectURL | Required | string | "" | The URL to redirect to after the user authorizes the client app. eg: https//localhost:5000/sign-in |
| signOutRedirectURL | Optional | string | The signInRedirectURL URL will be used if this value is not provided. | The URL to redirect to after the user | signs out. eg: https://localhost:5000/dashboard |
| clientHost | Optional | string | The origin of the client app obtained using window.origin | The hostname of the client app. eg: https://localhost:5000 |
| clientID | Required | string | "" | The client ID of the OIDC application hosted in the Asgardeo. |
| clientSecret | Optional | string | "" | The client secret of the OIDC application |
| enablePKCE | Optional | boolean | true | Specifies if a PKCE should be sent with the request for the authorization code. |
| prompt | Optional | string | "" | Specifies the prompt type of an OIDC request |
| responseMode | Optional | ResponseMode | "query" | Specifies the response mode. The value can either be query or form_post |
| scope | Optional | string[] | ["openid"] | Specifies the requested scopes. |
| serverOrigin | Required | string | "" | The origin of the Identity Provider. eg: https://www.asgardeo.io |
| endpoints | Optional | OIDCEndpoints | OIDC Endpoints Default Values | The OIDC endpoint URLs. The SDK will try to obtain the endpoint URLS | using the .well-known endpoint. If this fails, the SDK will use these endpoint URLs. If this attribute is not set, then the default endpoint URLs will be | used. However, if the overrideWellEndpointConfig is set to true, then this will override the endpoints obtained from the .well-known endpoint. |
| overrideWellEndpointConfig | Optional | boolean | false | If this option is set to true, then the endpoints object will override endpoints obtained | from the .well-known endpoint. If this is set to false, then this will be used as a fallback if the request to the .well-known endpoint fails. |
| wellKnownEndpoint | Optional | string | "/oauth2/token/.well-known/openid-configuration" | The URL of the .well-known endpoint. |
| validateIDToken | Optional | boolean | true | Allows you to enable/disable JWT ID token validation after obtaining the ID token. |
| clockTolerance | Optional | number | 60 | Allows you to configure the leeway when validating the id_token. |
| Attribute | Type | Description |
|---|---|---|
email |
string |
The email address of the user. |
username |
string |
The username of the user. |
displayName |
string |
The display name of the user. It is the preferred_username in the id token payload or the sub. |
allowedScopes |
string |
The scopes allowed for the user. |
tenantDomain |
string |
The tenant domain to which the user belongs. |
sessionState |
string |
The session state. |
| Method | Required/Optional | Type | Default Value | Description |
|---|---|---|---|---|
fidp |
Optional | string |
"" | The fidp parameter that can be used to redirect a user directly to an IdP's sign-in page. |
forceInit |
Optional | boolean |
false |
Forces obtaining the OIDC endpoints from the .well-known endpoint. A request to this endpoint is not sent if a request has already been sent. This forces a request. |
key: string |
Optional | string | boolean |
"" | Any key-value pair to be appended as path parameters to the authorization URL. |
| Method | Type | Default Value | Description |
|---|---|---|---|
authorizationEndpoint |
string |
"/oauth2/authorize" |
The authorization endpoint. |
tokenEndpoint |
string |
"/oauth2/token" |
The token endpoint. |
userinfoEndpoint |
string |
"" | The user-info endpoint. |
jwksUri |
string |
"/oauth2/jwks" |
The JWKS URI. |
registrationEndpoint |
string |
"" | The registration endpoint. |
revocationEndpoint |
string |
"/oauth2/revoke" |
The token-revocation endpoint. |
introspectionEndpoint |
string |
"" | The introspection endpoint. |
checkSessionIframe |
string |
"/oidc/checksession" |
The check-session endpoint. |
endSessionEndpoint |
string |
"/oidc/logout" |
The end-session endpoint. |
issuer |
string |
"" | The issuer of the token. |
wellKnownEndpoint |
string |
"/oauth2/token/.well-known/openid-configuration" |
The well-known endpoint. This is the default endpoint defined in the SDK. |
| Attribute | Required/Optional | Type | Default Value | Description |
|---|---|---|---|---|
id |
Required | string |
"" | Every custom-grant request should have an id. This attributes takes that id. |
data |
Required | any |
null |
The data that should be sent in the body of the custom-grant request. You can use template tags to send session information. Refer to the Custom Grant Template Tags section for more details. |
signInRequired |
Required | boolean |
false |
Specifies if the user should be sign-in or not to dispatch this custom-grant request. |
attachToken |
Required | boolean |
false |
Specifies if the access token should be attached to the header of the request. |
returnsSession |
Required | boolean |
false |
Specifies if the the request returns session information such as the access token. |
Session information can be attached to the body of a custom-grant request using template tags. This is useful when the session information is not exposed outside the SDK but you want such information to be used in custom-grant requests. The following table lists the available template tags.
| Tag | Data |
|---|---|
| "{{token}}" | The access token. |
| {{username}}" | The username. |
| "{{scope}}" | The scope. |
| {{clientID}}" | The client ID. |
| "{{clientSecret}}" | The client secret. |
| Method | Type | Description |
|---|---|---|
| aud | string | string[] |
The audience. |
| sub | string |
The subject. This is the username of the user. |
| iss | string |
The token issuer. |
string |
The email address. | |
| preferred_username | string |
The preferred username. |
| tenant_domain | string |
The tenant domain to which the user belongs. |
Node.js(version 10 or above).npmpackage manager.
The repository is a mono repository. The SDK repository is found in the oidc-js-sdk directory. You can install the dependencies by running the following command at the root.
npm run build
Please read Contributing to the Code Base for details on our code of conduct, and the process for submitting pull requests to us.
We encourage you to report issues, improvements, and feature requests creating Github Issues.
Important: And please be advised that security issues must be reported to security@wso2com, not as GitHub issues, in order to reach the proper audience. We strongly advise following the WSO2 Security Vulnerability Reporting Guidelines when reporting the security issues.
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
