diff --git a/en/asgardeo/docs/complete-guides/react/accessing-protected-api.md b/en/asgardeo/docs/complete-guides/react/accessing-protected-api.md new file mode 100644 index 0000000000..3cebf2af41 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/accessing-protected-api.md @@ -0,0 +1,146 @@ +--- +template: templates/complete-guide.html +heading: Accessing protected API from your React app +read_time: 2 min +--- + +In this section, we will focus on how to call a secure API from your React app using the other token—the access token. + +For simplicity, let's assume that the APIs we’re calling are secured by the same Identity Provider (IdP) and use the same issuer— in this case, the same {{product_name}} organization. This is typical when React apps are interacting with internal APIs within the same organization. + +!!! tip "Tip" + + If your app needs to call APIs secured by a different IdP, you’ll need to exchange your current access token for a new one issued by the IdP securing those APIs. This can be done using the OAuth2 token exchange grant type or other supported grant types. We will cover these scenarios in a separate guide. + +## Using SDK Built-in HTTP client + +You can use the `httpRequest` API provided by the Asgardeo SDK to make HTTP requests to these endpoints. This function is used to send http requests to {{product_name}} or desired backend. The developer doesn’t need to manually attach the access token since this function does it automatically. + +The following is a simple example of how you might use the Asgardeo SDK’s `httpRequest` to call a protected API endpoint, such as `/scim2/me` (to get the user profile details after signing in). In this case, the SCIM 2 endpoint is secured by the same {{product_name}} organization. {{product_name}} provides a SCIM 2 API for managing users within your organization. While user management with SCIM 2 is a topic for a different guide, we will use the API as part of our current guide. + +!!! note "Note" + + The storage type must be set to `webWorker` for the token to be automatically attached. If it’s set to `sessionStorage` or `localStorage`, you may implement your own function for attaching the access token to the network request. + +```javascript + +const App = () => { + + + const { httpRequest } = useAuthContext(); + + + const requestConfig = { + headers: { + "Accept": "application/json", + "Content-Type": "application/scim+json" + }, + method: "GET", + url: "https://api.asgardeo.io/t//scim2/me" + }; + + + useEffect(() => { + // Make a GET request to a protected endpoint + httpRequest(requestConfig) + .then((response) => { + // Handle successful response + console.log('Response:', response.data); + }) + .catch((error) => { + // Handle error + console.error('Error:', error); + }); + }, []) +} + +``` + +Note that you don’t need to manually specify the Authorization header under headers in `requestConfig`, as `httpRequest` function intercepts the request and attaches the access token to the network request as the Authorization header. + +In the above example, the final request config sent by the `httpRequest` function would be as follows + +```javascript +const requestConfig = { + headers: { + "Accept": "application/json", + "Content-Type": "application/scim+json", + "Authorization": "Bearer " + }, + method: "GET", + url: "https://api.asgardeo.io/t//scim2/me" + }; + + +``` + +In case you want to send multiple API requests in parallel, you can use the `httpRequestAll` function to simultaneously trigger parallel network requests and receive responses after all network requests are completed. + +The following code snippet shows a javascript function which accepts a list of application IDs and sends multiple network requests for each app ID in parallel. The responses will contain results for each id, as an array of responses. + +```javascript +import { AsgardeoSPAClient } from "@asgardeo/auth-react"; + + +const httpClientAll = AsgardeoSPAClient.getInstance() + .httpRequestAll.bind(AsgardeoSPAClient.getInstance()); + + +export const getApplicationsByIds = async (ids) => { + + + const requests = []; + + + for (const id of ids) { + requests.push({ + headers: { + "Accept": "application/json", + "Content-Type": "application/json" + }, + method: "GET", + url: "https://localhost:9443/applications/" + id + }); + } + + + try { + const responses = await httpClientAll(requests); + + + return Promise.resolve(responses); + } catch (error) { + console.error(error); + } +}; + +``` + +## Using a custom HTTP client + +In case you are not using the webWorker as the storage type, the `getAccessToken` function can be used to fetch the access token and manually attach it to the network request. The following is an example where the access token is fetched and manually attached to the authorization header of a Fetch request. + +```javascript +import { useAuthContext } from "@asgardeo/auth-react"; + + +const App = () => { + const { getAccessToken } = useAuthContext(); + + + useEffect(() => { + getAccessToken().then(async (accessToken) => { + const response = await fetch("https://api.asgardeo.io/t//scim2/me", { + "Authorization": "Bearer " + accessToken + }) + console.log(response) + }).catch((error) => { + console.log(error); + }); + }, []); + + . + . + . +} +``` diff --git a/en/asgardeo/docs/complete-guides/react/add-login-and-logout.md b/en/asgardeo/docs/complete-guides/react/add-login-and-logout.md new file mode 100644 index 0000000000..9085cf9fee --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/add-login-and-logout.md @@ -0,0 +1,78 @@ +--- +template: templates/complete-guide.html +heading: Add login and logout to your app +read_time: 2 min +--- + +Next, let’s implement login and logout for our React app. React hooks are a special type of functions that let you access state and other React features in React functional components. Asgardeo provides one such hook, `useAuthContext()`, to conveniently access user authentication data such as the logged in user’s information, etc and utility functions, such as a function to validate user’s authentication status, and retrieve access tokens. + +`useAuthContext` hook also provides us access with two key functions to perform sign in and sign out in your React application, `signIn` and `signOut` respectively. You can directly invoke the respective functions in our React application to trigger sign-in and sign-out requests as follows. + +Update the `App.jsx` with the following code. + +```javascript +import { useAuthContext } from "@asgardeo/auth-react"; +import './App.css'; + +const App = () => { +const { state, signIn, signOut } = useAuthContext(); + +return ( + <> + { + state.isAuthenticated + ? + : + } + +) +}; + +export default App; +``` + +Let’s look into the underlying details of what’s happening here. + +The `authConfig` object holds the configuration necessary for connecting the app to {{product_name}}. It includes properties like `signInRedirectURL` and `signOutRedirectURL`, which determine where users are redirected after signing in or out. The `clientID` identifies the application, and `baseUrl` specifies the Asgardeo API endpoint specific to your organization. The scope array lists the OAuth 2.0 permissions the app requires, such as `openid` and `profile`. The scops are used to indicate what user attributes are expected by our React app. + +The App component leverages the `useAuthContext` hook to access the authentication state (`state`) and actions (`signIn` and `signOut`). Inside the `AuthProvider`, the app conditionally renders a login or logout button based on whether the user is authenticated. If `state.isAuthenticated` is true, a "Logout" button is shown that triggers the `signOut` function. Otherwise, a "Login" button appears, which initiates the signIn process. + +Save the changes and re-run the application in development mode if it is not running already. + +```bash +npm run dev +``` + +Once the application is started, you will see the homepage of the application with the changes we made. + +![Login screen]({{base_path}}/complete-guides/react/assets/img/image14.png){: width="800" style="display: block; margin: 0;"} + +Initiate Sign In +Clicking on the login button will initiate an OIDC request. You will be able to observe the authorize request in the browser devtools as follows. To see this, right click on the application and click inspect and switch to the network tab. In the filter input, type “authorize”, and click on the sign in button. + +![OIDC request]({{base_path}}/complete-guides/react/assets/img/image15.png){: width="800" style="display: block; margin: 0;"} + +!!! tip "Tip" + + The OpenID Connect specification offers several functions, known as grant types, to obtain an access token in exchange for user credentials. This example uses the authorization code grant type. In this process, the app first requests a unique code from the authentication server, which can later be used to obtain an access token. For more details on the authorization code grant type, please refer to the [Asgardeo documentation.](https://wso2.com/asgardeo/docs/guides/authentication/oidc/implement-auth-code-with-pkce/){:target="_blank"} + +Asgardeo will receive this authorization request and respond by redirecting the user to a login page to enter their credentials. + +![OIDC request]({{base_path}}/complete-guides/react/assets/img/image16.png){: width="800" style="display: block; margin: 0;"} + +At this stage, **you need to create a [test user in Asgardeo](https://wso2.com/asgardeo/docs/guides/users/manage-users/#onboard-users){:target="_blank"} to try out the application.** Once you create a test user, you can enter the username and password of the test user to the login screen. + +If the login is successful, you should be able to see the application as shown below. + +![Login flow]({{base_path}}/complete-guides/react/assets/img/image17.png){: width="800" style="display: block; margin: 0;"} + +!!! tip "Tip" + + **PKCE (Proof Key for Code Exchange)** is an addition to the OAuth2 specification to make the authorization code more immune to replay attacks. It is enabled by default for public clients such as our single page React application. + + If you want to disable PKCE for some reason, you can do so via following the steps below. **However, disabling PKCE for public clients such as our single page React app is highly discouraged.** + - Log in to the {{product_name}} console and select the application you created. + - Switch to the Protocol tab. + - Uncheck the Mandatory checkbox under PKCE section. + +In this section, we have added login and logout features to our React app. In the next step, we will look into how to access the user attributes of the logged in user. diff --git a/en/asgardeo/docs/complete-guides/react/assets/img/image14.png b/en/asgardeo/docs/complete-guides/react/assets/img/image14.png new file mode 100644 index 0000000000..d758aefaa3 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/react/assets/img/image14.png differ diff --git a/en/asgardeo/docs/complete-guides/react/assets/img/image15.png b/en/asgardeo/docs/complete-guides/react/assets/img/image15.png new file mode 100644 index 0000000000..4cccdbec5c Binary files /dev/null and b/en/asgardeo/docs/complete-guides/react/assets/img/image15.png differ diff --git a/en/asgardeo/docs/complete-guides/react/assets/img/image16.png b/en/asgardeo/docs/complete-guides/react/assets/img/image16.png new file mode 100644 index 0000000000..d8a814ccf7 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/react/assets/img/image16.png differ diff --git a/en/asgardeo/docs/complete-guides/react/assets/img/image17.png b/en/asgardeo/docs/complete-guides/react/assets/img/image17.png new file mode 100644 index 0000000000..1f5f1092f8 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/react/assets/img/image17.png differ diff --git a/en/asgardeo/docs/complete-guides/react/assets/img/image18.png b/en/asgardeo/docs/complete-guides/react/assets/img/image18.png new file mode 100644 index 0000000000..a383eabaac Binary files /dev/null and b/en/asgardeo/docs/complete-guides/react/assets/img/image18.png differ diff --git a/en/asgardeo/docs/complete-guides/react/assets/img/image19.png b/en/asgardeo/docs/complete-guides/react/assets/img/image19.png new file mode 100644 index 0000000000..dc5197602d Binary files /dev/null and b/en/asgardeo/docs/complete-guides/react/assets/img/image19.png differ diff --git a/en/asgardeo/docs/complete-guides/react/assets/img/image20.png b/en/asgardeo/docs/complete-guides/react/assets/img/image20.png new file mode 100644 index 0000000000..0972bac78b Binary files /dev/null and b/en/asgardeo/docs/complete-guides/react/assets/img/image20.png differ diff --git a/en/asgardeo/docs/complete-guides/react/create-a-react-app.md b/en/asgardeo/docs/complete-guides/react/create-a-react-app.md new file mode 100644 index 0000000000..f8f65c1aea --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/create-a-react-app.md @@ -0,0 +1,39 @@ +--- +template: templates/complete-guide.html +heading: Create a React app +read_time: 2 min +--- + +For this guide, you will be creating a simple React app using [Vite](https://vitejs.dev/){:target="_blank"}, a modern, fast and lightweight tool that helps you quickly set up and develop modern JavaScript apps. + +Open a terminal, change directory to where you want to initialize the project, and run the following command to create your first React sample app. + + +```bash +npm create vite@latest asgardeo-react -- --template react +``` + +Running this command will create a folder with a ready-to-run boilerplate React project, with a development server to run the project and instantly reload changes to the project in your browser without manual refresh. + +Once the application is created, install the dependencies using the following command. + +```bash +cd asgardeo-react +npm install +``` + +Then run the sample in the development mode. This allows you to see real-time updates and debug the app as you make changes. + +```bash +npm run dev +``` + +Confirm that the dev server is up and running by verifying the following output in the terminal. + +![Dev server is runnig]({{base_path}}/complete-guides/react/assets/img/image13.png){: width="600" style="display: block; margin: 0;"} + +Navigate to [http://localhost:5173](http://localhost:5173){:target="_blank"} and you should see the sample app working in the browser. + +![Navigate to localhost]({{base_path}}/complete-guides/react/assets/img/image6.png){: width="600" style="display: block; margin: 0;"} + +At this point, you have a simple yet fully functional React app. In the next step, let’s try to integrate an OIDC SDK with the app. diff --git a/en/asgardeo/docs/complete-guides/react/create-a-react-application.md b/en/asgardeo/docs/complete-guides/react/create-a-react-application.md deleted file mode 100644 index bff9127a74..0000000000 --- a/en/asgardeo/docs/complete-guides/react/create-a-react-application.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -template: templates/complete-guide.html -heading: Create a React application -read_time: 2 min ---- - -If you want to try out with a sample application without going through this guide, you can use the sample React app [here](https://github.com/asgardeo/asgardeo-auth-react-sdk/tree/main/samples/asgardeo-react-app) with the necessary boilerplate. - -For this guide, you will be creating a simple React app using [Vite](https://vitejs.dev/), a modern, fast and lightweight tool that helps you quickly set up and develop modern JavaScript applications. Open a terminal, change directory to where you want to initialize the project, and run the following command to create your first React sample application. - -!!! note "Note" - - You need to have installed [Node.js](https://nodejs.org/en/download/package-manager) v18+ and npm (which comes inbuilt with Node) to run this sample. Although Node.js is primarily a server-side language,it needs to have been installed to manage dependencies and run scripts for our project. - -```bash -npm create vite@latest react-authentication-demo –- --template react -``` - -Running this command will create a folder with a ready-to-run boilerplate React project, with a development server to run the project and instantly reload changes to the project in your browser without manual refresh. - -Once the application is created, install the dependencies using the following command. - -```bash -cd react-authentication-demo -npm install -``` - -Then run the sample in the development mode. This allows you to see real-time updates and debug the application as you make changes. - -```bash -npm run dev -``` - -Confirm that the dev server is up and running by verifying the following output in the terminal. - -![Dev server is runnig]({{base_path}}/complete-guides/react/assets/img/image13.png){: width="600" style="display: block; margin: 0;"} - -Navigate to http://localhost:5173 and you should see the sample application working in the browser. - -![Navigate to localhost]({{base_path}}/complete-guides/react/assets/img/image6.png){: width="600" style="display: block; margin: 0;"} - -At this point, you have a simple yet fully functional React app. In the next step, let’s try to integrate an OIDC SDK with the app. diff --git a/en/asgardeo/docs/complete-guides/react/display-logged-in-user-details.md b/en/asgardeo/docs/complete-guides/react/display-logged-in-user-details.md new file mode 100644 index 0000000000..de87a4ec08 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/display-logged-in-user-details.md @@ -0,0 +1,133 @@ +--- +template: templates/complete-guide.html +heading: Display logged-in user details +read_time: 2 min +--- + +At this point, we’ve successfully implemented login and logout capabilities using the Asgardeo React SDK. The next step is to explore how to access and display logged-in user details within the app. The Asgardeo React SDK loads the basic user attribute details to the authentication state, so that you can directly access those from the state (such as `state.username`) and use them in the application. First, let’s try to display the username using state.username.Replace the code in app.jsx with the following. + +```javascript +import { useAuthContext } from "@asgardeo/auth-react"; +import './App.css'; + +const App = () => { + const { state, signIn, signOut } = useAuthContext(); + + return ( + <> + { + state.isAuthenticated + ? <> +

Welocme {state.username}

+ + + : + } + + ) +}; + +export default App; +``` + +If your React application is already running in the development mode, the home page will be reloaded and you will see the updated user interface. + +![Logout screen]({{base_path}}/complete-guides/react/assets/img/image18.png){: width="800" style="display: block; margin: 0;"} + +There may be instances where you’d need to retrieve user attributes outside React components. Asgardeo React SDK provides a [getBasicUserInfo](https://github.com/asgardeo/asgardeo-auth-react-sdk/blob/main/API.md#getbasicuserinfo){:target="_blank"} function, which allows you to retrieve the authenticated user’s basic information. The code example in the following section demonstrates this process and can be adapted to fit your application with any necessary customizations. + +Again, replace the code in `app.jsx` with the following. + +```javascript +import { useAuthContext } from "@asgardeo/auth-react"; +import { useEffect, useState } from "react"; +import './App.css'; + +const App = () => { + + const { state, getBasicUserInfo, signIn, signOut } = useAuthContext(); + const [userInfo, setUserInfo] = useState(undefined); + + useEffect(() => { + getBasicUserInfo().then((response) => { + setUserInfo(response) + }).catch((error) => { + console.error(error); + }); + }, [state]); + + + return ( + <> + { + state.isAuthenticated + ? <> +

Welcome, {userInfo?.username}

+ + + : + } + + ) +}; + +export default App; +``` + +The above code snippet, the app utilizes the `useAuthContext` hook to access authentication state and methods such as `getBasicUserInfo`, `signIn`, and `signOut`. It also uses React's `useState` to store basic user information and `useEffect` to fetch this information whenever the authentication state changes. If the user is authenticated, the app displays a welcome message with the username and a button to log out. If the user is not authenticated, it shows a login button that triggers the sign-in process, and the errors during user info retrieval are handled by logging them to the console. + +Similarly, you can access the other user attributes, such as email, display name, allowed scopes, etc as well. The following code snippet shows you how you can access them in your app. Asgardeo React SDK is responsible for processing the ID token and decoding these attributes. + +```javascript +

Your email: { userInfo?.email }

+

Display name: { userInfo?.displayName }

+

Allowed scopes: { userInfo?.allowedScopes }

+

Tenant domain: { userInfo?.tenantDomain }

+

Session state: { userInfo?.sessionState }

+``` + +## Getting additional user attributes + +Other than the above attributes decoded and available to you by default, Asgardeo React SDK provides [getDecodedIDToken](https://github.com/asgardeo/asgardeo-auth-react-sdk/blob/main/API.md#getdecodedidtoken){:target="_blank"} method to access any other user attributes that are not exposed by `getBasicUserInfo`. This method will decode the ID token in browser storage and return the output as a JSON object. + +To get additional user attributes to the ID token, the application should be configured to request the specific user attributes at the time of login. For example, if you want to retrieve a user's mobile number as an attribute, you need to configure the application to request the user’s mobile number as an attribute in the ID token. + +1. Log in to the {{product_name}} console and select the application you created. +2. Go to the **User Attributes** tab. +3. Select the **phone** scope. +4. Expand the scope, and you will see that all attributes under this scope (e.g., `mobile_number`) are selected. +5. Click Update to save the changes. + +```javascript + +const { state, signIn, signOut, getDecodedIDToken } = useAuthContext(); + + +const [mobileNumber, setMobileNumber] = useState("") + + +useEffect(() => { + if (state.isAuthenticated) { + getDecodedIDToken().then((decodedIdToken) => { + console.log(decodedIdToken); + setMobileNumber(decodedIdToken.phone_number) + }).catch((error) => { + console.log(error); + }) + } +}, [ state.isAuthenticated ]); + + +return ( + <> +

Your mobile number: {mobileNumber}

+ +) + +``` + +In the above code snippet, we run the `getDecodedIDToken` method if the user is authenticated, and print the output to the browser console. The decoded ID token response will be printed to the browser console as follows. + +![ID token]({{base_path}}/complete-guides/react/assets/img/image19.png){: width="800" style="display: block; margin: 0;"} + +In this step, we further improved our React app to display the user attributes. As the next step, we will try to secure routes within the app. diff --git a/en/asgardeo/docs/complete-guides/react/install-asgardeo-sdk.md b/en/asgardeo/docs/complete-guides/react/install-asgardeo-sdk.md new file mode 100644 index 0000000000..e124a9be83 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/install-asgardeo-sdk.md @@ -0,0 +1,72 @@ +--- +template: templates/complete-guide.html +heading: Install and configure Asgardeo SDK +read_time: 2 min +--- + +## Install @asgardeo/auth-react + +The Asgardeo React SDK is a production-ready SDK that simplifies integrating {{product_name}} as an Identity Provider in your React applications.It provides essential features like user authentication, retrieving user information, and an HTTP client for sending network requests with attached tokens. Additionally, it ensures best practices by being Secure by Design and Secure by Default. + +!!! tip "Tip" + + Asgardeo React SDK has been developed on open standards such as OAuth2, OpenID Connect etc, therefore you can use the Asgardeo React SDK for adding authentication to your application with any other OpenID Connect identity provider such as [WSO2 Identity Server (WSO2 IS)](https://wso2.com/identity-server/){:target="_blank"} and WSO2 [Private Identity Cloud (WSO2 PIC)](https://wso2.com/private-identity-cloud/){:target="_blank"} . + +As the next step, run the following command to install the React SDK from the npm registry. + +```bash +npm install @asgardeo/auth-react + +``` + +## Add `` to your app + +During the previous step, we have added Asgardeo React SDK as a dependency in our app. Now we are going to use the `` component from the Asgardeo React SDK which is built on top of [React Context](https://react.dev/learn/passing-data-deeply-with-context){:target="_blank"}. The `` serves as a context provider for user login in the app. You can add the `` to your app by wrapping the root component to access authentication-related capabilities throughout the component tree. + +First, you need to open the project using an IDE such as VS Code. Then, as shown below, you need to wrap the **** component in `main.jsx` with the `` component. Make sure to replace the placeholders in this code from the configuration parameters that we generated in [step-3](http://localhost:8000/asgardeo/docs/complete-guides/react/register-an-application/). + +```javascript +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App.jsx'; +import { AuthProvider } from '@asgardeo/auth-react'; +import './index.css'; + +const config = { + signInRedirectURL: "http://localhost:5173", + signOutRedirectURL: "http://localhost:5173", + clientID: "", + baseUrl: "https://api.asgardeo.io/t/", + scope: [ "openid","profile" ] +} + +ReactDOM.createRoot(document.getElementById('root')).render( + + + + +, +); + +``` + +As shown above, we used `` at the root level of the application to ensure that all components can interact with the authentication logic provided by {{product_name}}. It takes the configuration object with the following values for the single page application defined in the {{product_name}} console. You can copy these values from the {{product_name}} console. + +| Parameter | Description | Example | +|-----------------------|----------------------------------------------------------------------------------------------------------------------|-----------------------------------| +| signInRedirectURL | The URL to redirect the user to after successfully signing in. This URL should be an absolute URL and only accessible to authenticated users. | `http://localhost:5173` | +| signOutRedirectURL | The URL to redirect the user to after signing out. This should be an absolute URL and should be accessible without authentication. | `http://localhost:5173/login` | +| clientID | The client ID of the created OIDC application | - | +| baseUrl | The base URL of the Identity Provider API. This depends on the identity provider you are using. For {{product_name}}, this can be obtained from your application settings in the {{product_name}} console. | `https://www.asgardeo.io/t/` | +| scope | Specifies the required application scopes as a list. In this guide, we need access to user details, so we will request the 'profile' scope. | `[ "profile" ]` | + +!!! note "Note" + + If you’re familiar with OAuth2 or OIDC, you might notice that there’s no client secret involved here. This is because, according to the OAuth2 specification, our React app is classified as a public client. Since it runs on user devices and cannot securely store credentials, the Identity Provider (IdP) should not authenticate public clients before issuing access tokens. The {{product_name}} SDK addresses this by implementing the PKCE (Proof Key for Code Exchange) extension, which helps mitigate the security risks associated with public clients + +Here’s a brief overview of what `` provides: + +* **Context Management:** It creates a context that holds the authentication state and methods to handle authentication actions like logging in, logging out, and checking the user's authentication status. +* **Session Handling:** `` manages user sessions, including token storage and retrieval, token refresh, and user session expiration handling. +* **Easy Access to Authentication:** By wrapping your app with ``, any component within your app can easily access authentication details and actions using hooks like useAuthContext. +* **Initialization and Configuration:** It initializes the SDK with the necessary configuration, such as client ID, server endpoints, and other authentication settings. diff --git a/en/asgardeo/docs/complete-guides/react/introduction.md b/en/asgardeo/docs/complete-guides/react/introduction.md index 234c7171e0..f6e4e7c512 100644 --- a/en/asgardeo/docs/complete-guides/react/introduction.md +++ b/en/asgardeo/docs/complete-guides/react/introduction.md @@ -3,45 +3,27 @@ template: templates/complete-guide.html heading: Introduction read_time: 2 mins --- - -## Why do you need user login - -React is a widely used JavaScript library designed for creating dynamic single-page applications (SPAs). It enables developers to build responsive interfaces by breaking down complex UIs into reusable components. Unlike traditional UI technologies, React updates specific parts of the page without re-rendering the entire page, thanks to its virtual DOM. This capability makes React popular for developing SPAs. +React is a widely used JavaScript library designed for creating dynamic single-page apps (SPAs). It enables developers to build responsive interfaces by breaking down complex UIs into reusable components. Unlike traditional UI technologies, React updates specific parts of the page without re-rendering the entire page, thanks to its virtual DOM. This capability makes React popular for developing SPAs. Implementing login functionality in your React app is essential for managing user access, personalizing user experiences, and securing the app. It enhances user experience, protects user data, boosts engagement, and helps ensure regulatory compliance. -![Should I worry about adding user login?]({{base_path}}/complete-guides/react/assets/img/image4.png){: width="600" style="display: block; margin: 0;"} - - -## D.I.Y or use an Identity Provider (IdP) - -It’s perfectly okay to implement login for your React app by yourself. As a starting step, you may add a login page and store usernames and passwords in a database . However, this approach will not be scalable in the long run because: - -1. User login becomes complex over time with the need for features like multi-factor authentication (MFA), adaptive authentication, passwordless login, social login, and Single Sign-On (SSO). -2. Account management becomes complex with requirements like password policies, password resets, forgotten usernames, and onboarding from social platforms. - -![How should I add user login?]({{base_path}}/complete-guides/react/assets/img/image3.png){: width="600" style="display: block; margin: 0;"} -Fortunately, there are production-grade authentication providers and login SDKs available to simplify these tasks for you. Integrating your app with an identity provider simplifies user login and ensures secure access to resources, offloading complex tasks like credential management and session handling. In this guide, you'll be using Asgardeo as the IdP. If you don’t have Asgardeo you can instantly sign-up for a free account from [here]. Asgardeo offers a generous free tire account that is more than enough during the app development phase. +## Learning objectives -## Build secure apps using SDKs +This guide will walk you through everything you need to know about securing React apps, including implementing user login in your React app, integrating it with an Identity Provider (IdP) to make the login process simple and secure, and general guidelines to protect your end users.This guide will walk you through everything you need to know about securing React applications, including implementing user login, integrating with an Identity Provider (IdP) for a simple and secure login process, and general guidelines to protect your end users. It also covers how to make secure API calls to an OAuth2-protected API within your React app. -If you are going down the path of integrating with an Identity Provider (IdP), again you have two options: +In this guide, you will: -1. **Do it yourself (D.I.Y):** You can implement OIDC request-response flows and token processing yourself using a combination of React features and JavaScript. This approach gives you full control over the authentication process but requires a deeper understanding of OIDC protocols and a significant investment of time to ensure secure and reliable implementation. -2. **Using a React SDK:** Alternatively, you can integrate a production-ready React SDK into your app. This approach simplifies the implementation of login by providing pre-built methods for handling sign-ins, token management, and session control. The SDK manages complex and sensitive processes like token validation and renewal, enhancing security while reducing development time. - -![How should integrate wiuth an IdP?]({{base_path}}/complete-guides/react/assets/img/image2.png){: width="600" style="display: block; margin: 0;"} - -This guide will walk you through everything you need to know about securing React applications, including implementing user login in your React app, integrating it with an Identity Provider (IdP) to make the login process simple and secure, and general guidelines to protect your end users. - -Here is the order you are going to follow throughout this guide: - -* Register an application in Asgardeo/IS -* Create a React application -* Install Asgardeo React SDK +* Register an application in {{product_name}} +* Create a React app +* Install {{product_name}} React SDK * Add login and logout to your app * Display logged in user detail * Securing routes within the app * Accessing protected API from your React app -* Token management in React app +* Managing tokens in your React app + + +!!! tip "Tip" + + If you want to quickly build a React app and user login, try the [React Quick Start guide.](https://wso2.com/asgardeo/docs/quick-starts/react/){:target="_blank"} It takes around 15 minutes. diff --git a/en/asgardeo/docs/complete-guides/react/manage-tokens-in-React-apps.md b/en/asgardeo/docs/complete-guides/react/manage-tokens-in-React-apps.md new file mode 100644 index 0000000000..ae33c5612a --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/manage-tokens-in-React-apps.md @@ -0,0 +1,135 @@ +--- +template: templates/complete-guide.html +heading: Manage tokens in React apps +read_time: 2 min +--- + +## Token Validation + +A key principle of security tokens is that the receiver must first validate the token. This involves checking the authenticity of the token issuer, ensuring the token meets validity criteria such as expiration time, and confirming that the receiver is authorized to use the token. The Asgardeo React SDK handles token validation automatically as part of its authentication and session management process to ensure that users have valid and unexpired tokens when accessing protected resources. + +When a user signs in, the Asgardeo React SDK acquires an access token (and often an ID token) from {{product_name}}. The access token is by default an opaque token and the ID token is in the form of JSON Web Tokens (JWTs). The SDK automatically validates the token when it is obtained. This involves several checks: + +- **Signature Validation:** The SDK verifies the JWT's signature using the public key retrieved from {{product_name}} JWKS endpoint. This ensures that the token has been issued by a trusted authority and has not been tampered with. + +- **Expiration Check:** The SDK checks the `exp` (expiration) claim in the token to ensure it has not expired. Tokens are time-bound, and once the expiration time is reached, the token is considered invalid. + +- **Issuer Validation:** The SDK verifies that the `iss` (issuer) claim in the token matches the expected issuer URL, which is typically the base URL specified in the `authConfig`. + +- **Audience Validation:** The SDK checks the aud (audience) claim to ensure the token is intended for your application (identified by the `clientID` in your `authConfig`). + +If the token is close to being expired, the SDK will automatically attempt to renew the token by performing a silent sign-in (explained below). This helps maintain a seamless user experience without requiring the user to re-authenticate frequently. If the token has already expired and cannot be renewed silently, the user will be redirected to the login page to obtain a new token. + +## Token Persistence + +In the Asgardeo React SDK, the state storage mechanism determines where the authentication state, tokens, and other related data are stored. By default, Asgardeo React SDK uses session storage, but you can configure the SDK to use other storage options like local storage or even a web worker. + +You can specify the storage mechanism in the authConfig object using the storage property. Here's how you can configure it for different storage types. + +- **Local Storage:** localStorage stores data across browser sessions, meaning the data persists even after the browser is closed and reopened. + +```javascript + +const authConfig = { + // other configs + storage: "localStorage" +} + +``` + +- **Session Storage:** sessionStorage stores data for the duration of the page session. The data is cleared when the page session ends (e.g., when the tab is closed). + +```javascript + +const authConfig = { + // other configs + storage: "sessionStorage" +} + + +``` + +- **Web Worker:** Using a web worker allows state to be managed in a separate thread, which can be beneficial for performance and security. + +```javascript + +const authConfig = { + // other configs + storage: "webWorker" +} + +``` + +Compared to other methods for persisting tokens, web workers are the most secure option, due to the following reasons. + +- **Performance**: Web workers run in a separate thread from the main JavaScript execution, offloading tasks like handling authentication state, which reduces the load on the main thread and leads to smoother UI interactions. + +- **Security:** Operating in isolation from the DOM, web workers reduce the risk of cross-site scripting (XSS) attacks by keeping sensitive authentication data secure. + +- **Asynchronous** Task Management: Web workers enhance the handling of asynchronous tasks, such as token renewal or data fetching, without blocking the main thread. + +- **Scalability:** By enabling parallelism, web workers make applications more responsive and better equipped to handle multiple concurrent operations. + +## Initiate Logout + +The Asgardeo React SDK provides a simple approach to handle user logout from your app. When a user logs out, the SDK ensures that both the local session and the session on the {{product_name}} are terminated, ensuring a complete and secure logout process and you don’t need to worry on cleanup activities + +When a user initiates log out, the following steps typically occur. + +- **Local Session Termination:** The SDK clears any locally stored credentials, such as the access token and the ID token, which are used to maintain the user's authentication state within the application. This effectively logs the user out of the application locally. + +- **Redirection to {{product_name}} for sign out:** After clearing the local session, the SDK redirects the user to the sign-out endpoint of your {{product_name}} organization. This ensures that the user is also signed out globally from {{product_name}}. It’s particularly important in single sign-on (SSO) scenarios where the user might be logged into multiple applications under the same identity. + +- **Post Sign-Out Redirection:** Once the global sign-out is complete, the user is redirected back to a specified URL, usually the application's homepage or a custom logout page, which is configured in the SDK's authConfig under signOutRedirectURL. + +## Silent Sign In + +Silent login allows an app to check if a user is already authenticated, either through a session cookie or a token stored in the browser, and re-authenticate automatically in the background. To implement silent sign-in using the Asgardeo React SDK, you can leverage the library's built-in support for token renewal and session management. Here's how you can do it: + +- **Configure the Silent Sign-In:** Ensure that your `authConfig` is set up to allow silent sign-in. You need to configure the prompt parameter to `none` when initiating a silent sign-in request. This instructs the identity provider to not display any login prompts and to rely on existing sessions instead. + +- **Use the SDK’s Built-in Functionality:** The Asgardeo React SDK typically handles silent token renewal automatically if the configuration is set correctly. When the access token is about to expire, the SDK will attempt to renew it silently in the background. + +- **Handling Token Expiry:** In your React components, you can handle token expiry by checking the authentication state and initiating a silent sign-in if the user’s session is still valid but the token has expired. + +```javascript + +import { AuthProvider, useAuthContext } from "@asgardeo/auth-react"; + + +const authConfig = { + signInRedirectURL: "http://localhost:5173", + signOutRedirectURL: "http://localhost:5173", + clientID: "", + baseUrl: "https://api.asgardeo.io/t/", + scope: ["openid", "profile"], + enableSilentSignIn: true // Enable silent sign-in +}; + + +const App = () => { + const { state, signIn } = useAuthContext(); + + + React.useEffect(() => { + if (!state.isAuthenticated) { + signIn({ prompt: "none" }).catch(() => { + // Handle silent sign-in failure + }); + } + }, [state.isAuthenticated, signIn]); + + + return ( + + {/* App content */} + + ) +} + + +export default App; +useAuthContext + + +``` diff --git a/en/asgardeo/docs/complete-guides/react/next-steps.md b/en/asgardeo/docs/complete-guides/react/next-steps.md new file mode 100644 index 0000000000..646c867832 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/next-steps.md @@ -0,0 +1,40 @@ +--- +template: templates/complete-guide.html +heading: Next Steps +read_time: 1 min +--- + +This guide you just have completed, covered the adding user login for React apps by integrating with an Identity Provider (IdP) and additional use cases such making calls to an OAuth2-protected API. + +Now that you are familiar with the basics of adding user logins to your React app, you can use the [Asgardeo Vite React Template](https://github.com/asgardeo/asgardeo-vite-react-template){:target="_blank"} to generate a working sample without needing to write code from scratch. After creating an application in the Asgardeo console and copying the necessary parameters, run the following command to create your working sample. + +```bash + +npx tmplr --dir my-vite-react-app asgardeo/asgardeo-vite-react-template + +``` + +The above command generates a working React app with pre-configured Asgardeo React SDK and login/logout features that you can use to build your app further. + +![Asgardeo Vite React Template]({{base_path}}/complete-guides/react/assets/img/image20.png){: width="800" style="display: block; margin: 0;"} + + +You can quickly test the integration of your newly created React app with {{product_name}} by running the following commands. + + +```bash + +cd my-vite-react-app + +npm install + +npm run dev + +``` + +Now that your React application is secured with authentication features integrated, It is time to explore the additional features {{product_name}} offers to make the login flow more diverse and secure. + +- [Multi factor authentication](https://wso2.com/asgardeo/docs/guides/authentication/mfa/){:target="_blank"} +- [Passwordless authentication](https://wso2.com/asgardeo/docs/guides/authentication/passwordless-login/){:target="_blank"} +- [Self registration](https://wso2.com/asgardeo/docs/guides/user-accounts/configure-self-registration/){:target="_blank"} +- [Login UI customization](https://wso2.com/asgardeo/docs/guides/branding/){:target="_blank"} diff --git a/en/asgardeo/docs/complete-guides/react/prerequisite.md b/en/asgardeo/docs/complete-guides/react/prerequisite.md index ec49be1ea2..e2f83d30b0 100644 --- a/en/asgardeo/docs/complete-guides/react/prerequisite.md +++ b/en/asgardeo/docs/complete-guides/react/prerequisite.md @@ -7,11 +7,12 @@ read_time: 30 secs ## Before you start, ensure you have the following: * About 60 minutes -* Asgardeo account -* Install a JS package manager +* {{product_name}} account +* [Node.js](https://nodejs.org/en/download/package-manager){:target="_blank"} v18+ and npm * A favorite text editor or IDE -!!! tip "Tip" - - If you want to quickly build a React application, try the React Quick Start guide here. It takes around 15 minutes. +!!! note "Note" + + You need to have installed [Node.js](https://nodejs.org/en/download/package-manager){:target="_blank"} v18+ and npm (which comes inbuilt with Node) to run this sample. Although Node.js is primarily a server-side language,it needs to have been installed to manage dependencies and run scripts for our project. + diff --git a/en/asgardeo/docs/complete-guides/react/register-an-application-in-asgardeo-is.md b/en/asgardeo/docs/complete-guides/react/register-an-application-in-asgardeo-is.md deleted file mode 100644 index 778749e4b0..0000000000 --- a/en/asgardeo/docs/complete-guides/react/register-an-application-in-asgardeo-is.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -template: templates/complete-guide.html -heading: Register an application in Asgardeo/IS -read_time: 2 min ---- - -First unless you already have done that, you need to create an organization in Asgardeo and register your application as a single page application. - -* Sign up for a free Asgardeo account at wso2.com/asgardeo -* Sign into Asgardeo console and navigate to Applications > New Application. -* Select Single Page Application - -![Select Single Page Application]({{base_path}}/complete-guides/react/assets/img/image5.png){: width="600" style="display: block; margin: 0;"} - -Complete the wizard popup by providing a suitable name and an authorized redirect URL. - -![Register a new application]({{base_path}}/complete-guides/react/assets/img/image8.png){: width="600" style="display: block; margin: 0;"} - -!!! note "Note" - - The authorized redirect URL determines where Asgardeo should send users after they successfully log in. Typically, this will be the web address where your application is hosted. For this guide, we'll use http://localhost:5173, as the sample application will be accessible at this URL. - -!!! tip "Hint" - - Use the information available in the Quick Start tab of your app or the Quickstart guide under the React SDK for the AuthProvider config. - -![Quick start guide]({{base_path}}/complete-guides/react/assets/img/image9.png){: width="600" style="display: block; margin: 0;"} diff --git a/en/asgardeo/docs/complete-guides/react/register-an-application.md b/en/asgardeo/docs/complete-guides/react/register-an-application.md new file mode 100644 index 0000000000..755f801fcf --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/register-an-application.md @@ -0,0 +1,34 @@ +--- +template: templates/complete-guide.html +heading: Register an application in Asgardeo +read_time: 2 min +--- + +First unless you already have done that, you need to create an organization in {{product_name}} and register your application as a single page application. + +* Sign up for a [free {{product_name}} account](https://wso2.com/asgardeo/docs/get-started/create-asgardeo-account/){:target="_blank"} +* Sign into {{product_name}} console and navigate to **Applications > New Application.** +* Select Single Page Application + +![Select Single Page Application]({{base_path}}/complete-guides/react/assets/img/image5.png){: width="600" style="display: block; margin: 0;"} + +Next, complete the wizard popup by providing a suitable name and an authorized redirect URL. + +![Register a new application]({{base_path}}/complete-guides/react/assets/img/image8.png){: width="600" style="display: block; margin: 0;"} + +!!! note "Note" + + The authorized redirect URL determines where {{product_name}} should send users after they successfully log in. Typically, this will be the web address where your app is hosted. For this guide, we'll use [http://localhost:5173](http://localhost:5173){:target="_blank"}, as the sample app will be accessible at this URL. + + + +You will need the following information available in the Quick Start tab of your app or the Quickstart guide under the React SDK for the `AuthProvider` config. + +* Client ID +* Base URL +* Redirect URL +* Scope + +![Quick start guide]({{base_path}}/complete-guides/react/assets/img/image9.png){: width="600" style="display: block; margin: 0;"} + +In this step, we have ve registered our React app as an application in the {{product_name}} console and generated the required metadata. Next, we will create a React app using Vite. diff --git a/en/asgardeo/docs/complete-guides/react/securing-routes-within-the-app.md b/en/asgardeo/docs/complete-guides/react/securing-routes-within-the-app.md new file mode 100644 index 0000000000..f2d22cb37d --- /dev/null +++ b/en/asgardeo/docs/complete-guides/react/securing-routes-within-the-app.md @@ -0,0 +1,131 @@ +--- +template: templates/complete-guide.html +heading: Securing Routes within the app +read_time: 2 min +--- + +In a React app, routes define the paths within the application that users can navigate to, linking URLs to specific components. Securing routes is essential to protect sensitive data, prevent unauthorized access, and ensure that only authenticated users can access certain parts of the application. In this section, let’s look at how we can secure routes using Asgardeo React SDK + +The Asgardeo SDK provides multiple approaches to secure routes in your application. Here we will demonstrate how to secure routes in a single-page React app using [React Router v6](https://reactrouter.com/en/main){:target="_blank"} , the most popular routing library for React. The same approach can be applied to other routing libraries such as [TanStack Router](https://tanstack.com/router/latest){:target="_blank"} and [Wouter](https://github.com/molefrog/wouter){:target="_blank"}, etc. + +## Using `` + +Asgardeo React SDK provides the `SecureApp` component, using which you can wrap the whole app or a part of the app that needs to have secure access. Then all the views wrapped with the SecureApp component are not accessible to an unauthenticated user. + +```javascript + + + } + onSignIn={ onSignInFunction } + overrideSignIn={ overrideSignInFunction } + > + + + + +``` + +In the above example, the `SecureApp` component wraps the entire App component, restricting all unauthorized users from accessing any part of our React application. It displays a fallback UI component while the authentication status is being resolved, and accepts a callback function to trigger after the sign in is successful. + +## Using `` + +`AuthenticatedComponent` is another component provided by the Asgardeo React SDK to conditionally display UI elements based on the user's authentication status. You can use this to implement secure routes with react router in our app. + +```javascript + +import { AuthProvider } from '@asgardeo/auth-react' +import { BrowserRouter as Router, Routes, Route } from 'react-router-dom' +import LoginPrompt from './components/login-prompt' +import Home from './pages/home' +import Dashboard from './pages/dashboard' +import './App.css' + +const config = { + signInRedirectURL: "http://localhost:5173", + signOutRedirectURL: "http://localhost:5173", + clientID: "0Fo7kLavZtHAVtXRr1zzpjwzeBMa", + baseUrl: "https://api.asgardeo.io/t/pavindu119", + scope: [ "openid","profile" ] +} + +function App() { + + return ( + Initializing...

}> + + + } /> + + +
+ } + /> + + +
+ ) +} + +export default App + +``` + +This code snippet defines a route in a React application using the Route component from react-router-dom. It specifies that when the user navigates to the /dashboard path, the AuthenticatedComponent should be rendered. Let’s break down the code to understand what’s going on behind the scenes. + +- `path="/dashboard"`: This sets the URL path for this route. When the user visits `/dashboard`, the specified component will be rendered. + +- `element={...}`: defines the component(s) that will be rendered for this route. In this case, it’s the Dashboard UI view wrapped with AuthenticatedComponent. + +- `AuthenticatedComponent`: This is a React component provided by the Asgardeo React SDK that checks if the user is authenticated. It wraps around the Dashboard component to secure it. + +- `fallbackComponent={LoginPrompt}`: If the user is not authenticated, the AuthenticatedComponent will render the LoginPrompt component instead of the Dashboard component, prompting the user to log in. + +- ``: This is the main component that will be rendered if the user is authenticated and has access to the /dashboard route. + +## Bring your own implementation + +If you prefer to have full control over how the app routes should be secured—for example, if you want to run custom application logic before enabling or disabling a route—you can also build a completely custom logic using the primitives provided by the Asgardeo React SDK out of the box. + +```javascript + +const App = () => { + + const ProtectedRoute = ({ children }: { children: ReactNode }) => { + + + const { state } = useAuthContext(); + + + if (!state.isAuthenticated) { + return ; + } + + + return children; + }; + + + return ( + + + + + } + /> + } /> + } /> + + ) +}; + + +``` + +In this step, we looked into how to secure component routes within a React app. Next, we will try to access a protected API from our React app, which is a common requirement for SPAs. diff --git a/en/asgardeo/mkdocs.yml b/en/asgardeo/mkdocs.yml index 2481d9841f..7a9ba0c6cb 100644 --- a/en/asgardeo/mkdocs.yml +++ b/en/asgardeo/mkdocs.yml @@ -492,10 +492,17 @@ nav: - Financial-grade API: references/financial-grade-api.md - App-native authentication: references/app-native-authentication.md - React Guide: - - Intruduction: complete-guides/react/introduction.md + - Introduction: complete-guides/react/introduction.md - Prerequisite: complete-guides/react/prerequisite.md - - Register an application in Asgardeo/IS: complete-guides/react/register-an-application-in-asgardeo-is.md - - Create a React application: complete-guides/react/create-a-react-application.md + - Configure an application: complete-guides/react/register-an-application.md + - Create a React app: complete-guides/react/create-a-react-app.md + - Configure Asgardeo SDK: complete-guides/react/install-asgardeo-sdk.md + - Add login and logout: complete-guides/react/add-login-and-logout.md + - Display user details: complete-guides/react/display-logged-in-user-details.md + - Securing Routes: complete-guides/react/securing-routes-within-the-app.md + - Accessing protected API : complete-guides/react/accessing-protected-api.md + - Manage tokens in React : complete-guides/react/manage-tokens-in-React-apps.md + - Next Steps: complete-guides/react/next-steps.md not_in_nav: | /page-not-found.md