diff --git a/en/asgardeo/docs/complete-guides/vue/accessing-protected-api.md b/en/asgardeo/docs/complete-guides/vue/accessing-protected-api.md new file mode 100644 index 0000000000..2c1ce02b6c --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/accessing-protected-api.md @@ -0,0 +1,134 @@ +--- +template: templates/complete-guide.html +heading: Accessing protected API from your Vue app +read_time: 2 min +--- + +In this section, we will focus on how to call a secure API from your Vue 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 Vue 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 +import { useAsgardeo } from "@asgardeo/vue"; +import { onMounted } from "vue"; + +export default { + setup() { + const { httpRequest } = useAsgardeo(); + + const requestConfig = { + headers: { + Accept: "application/json", + "Content-Type": "application/scim+json", + }, + method: "GET", + url: "https://api.asgardeo.io/t//scim2/me", + }; + + onMounted(() => { + httpRequest(requestConfig) + .then((response) => { + console.log("Response:", response.data); + }) + .catch((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 function that 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 { useAsgardeo } from "@asgardeo/vue"; + +export default { + setup() { + const { httpRequestAll } = useAsgardeo(); + + const getApplicationsByIds = async (ids) => { + const requests = ids.map((id) => ({ + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + method: "GET", + url: "https://localhost:9443/applications/" + id, + })); + + try { + const responses = await httpRequestAll(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 { useAsgardeo } from "@asgardeo/vue"; +import { onMounted } from "vue"; + +export default { + setup() { + const { getAccessToken } = useAsgardeo(); + + onMounted(() => { + getAccessToken() + .then(async (accessToken) => { + const response = await fetch( + "https://api.asgardeo.io/t//scim2/me", + { + headers: { + Authorization: "Bearer " + accessToken, + }, + } + ); + console.log(response); + }) + .catch((error) => { + console.log(error); + }); + }); + }, +}; +``` diff --git a/en/asgardeo/docs/complete-guides/vue/add-login-and-logout.md b/en/asgardeo/docs/complete-guides/vue/add-login-and-logout.md new file mode 100644 index 0000000000..a2a1c3eef7 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/add-login-and-logout.md @@ -0,0 +1,77 @@ +--- +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 Vue app. Asgardeo provides a composable, `useAsgardeo()`, to conveniently access user authentication data and utility functions. + +`useAsgardeo` composable gives you access to two key functions to perform sign in and sign out in your Vue application, `signIn` and `signOut` respectively. You can directly invoke these functions to trigger sign-in and sign-out requests. + +Update your component with the following code: + +```vue + + + +``` + +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 component leverages the `useAsgardeo` composable to access the authentication state (`state`) and actions (`signIn` and `signOut`). The template conditionally renders login or logout buttons based on whether the user is authenticated. + +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/vue/assets/img/image6.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/vue/assets/img/image10.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/vue/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/vue/assets/img/image1.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 Vue 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 Vue app is highly discouraged.** + + 1. Log in to the {{product_name}} console and select the application you created. + 2. Switch to the Protocol tab. + 3. Uncheck the Mandatory checkbox under PKCE section. + +In this section, we have added login and logout features to our Vue 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/vue/assets/img/image1.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image1.png new file mode 100644 index 0000000000..ef29b93f8e Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image1.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image10.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image10.png new file mode 100644 index 0000000000..24b1240c12 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image10.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image11.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image11.png new file mode 100644 index 0000000000..2840ed6e16 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image11.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image12.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image12.png new file mode 100644 index 0000000000..ab1b9c4f8f Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image12.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image13.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image13.png new file mode 100644 index 0000000000..d929e57039 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image13.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image16.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image16.png new file mode 100644 index 0000000000..d8a814ccf7 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image16.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image2.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image2.png new file mode 100644 index 0000000000..f9f9ba0fc4 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image2.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image3.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image3.png new file mode 100644 index 0000000000..39a39a130b Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image3.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image4.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image4.png new file mode 100644 index 0000000000..2b9c046ef1 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image4.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image5.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image5.png new file mode 100644 index 0000000000..b5b9bdb6ca Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image5.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image6.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image6.png new file mode 100644 index 0000000000..2840ed6e16 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image6.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image7.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image7.png new file mode 100644 index 0000000000..767e4bed0a Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image7.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image8.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image8.png new file mode 100644 index 0000000000..e10051c0ad Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image8.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/assets/img/image9.png b/en/asgardeo/docs/complete-guides/vue/assets/img/image9.png new file mode 100644 index 0000000000..4ce40ad4c3 Binary files /dev/null and b/en/asgardeo/docs/complete-guides/vue/assets/img/image9.png differ diff --git a/en/asgardeo/docs/complete-guides/vue/create-a-vue-app.md b/en/asgardeo/docs/complete-guides/vue/create-a-vue-app.md new file mode 100644 index 0000000000..f16ea6151a --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/create-a-vue-app.md @@ -0,0 +1,35 @@ +--- +template: templates/complete-guide.html +heading: Create a Vue app +read_time: 1 min +--- + +For this guide, you will be creating a simple Vue 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 Vue sample app. + + +```bash +npm create vite@latest asgardeo-vue -- --template vue-ts +``` + +Running this command will create a folder with a ready-to-run boilerplate Vue 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-vue +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 output in the terminal. Then, 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/vue/assets/img/image6.png){: width="600" style="display: block; margin: 0;"} + +At this point, you have a simple yet fully functional Vue app. In the next step, let's try to integrate an OIDC SDK with the app. diff --git a/en/asgardeo/docs/complete-guides/vue/display-logged-in-user-details.md b/en/asgardeo/docs/complete-guides/vue/display-logged-in-user-details.md new file mode 100644 index 0000000000..8dc9e3d232 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/display-logged-in-user-details.md @@ -0,0 +1,145 @@ +--- +template: templates/complete-guide.html +heading: Display logged-in user details +read_time: 3 min +--- + +At this point, we've successfully implemented login and logout capabilities using the Asgardeo Vue SDK. The next step is to explore how to access and display logged-in user details within the app. The Asgardeo Vue SDK loads the basic user attribute details into 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 your component with the following: + +```javascript +{% raw %} + + + +{% endraw %} +``` + +If your Vue application is already running in development mode, the home page will be reloaded, and you will see the updated user interface. + +![Logout screen]({{base_path}}/complete-guides/vue/assets/img/image1.png){: width="800" style="display: block; margin: 0;"} + +There may be instances where you'd need to retrieve user attributes outside Vue components. The Asgardeo Vue SDK provides a `getBasicUserInfo` 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 your component with the following: + +```javascript +{% raw %} + + + +{% endraw %} +``` + +In the above code snippet, the app utilizes the `useAsgardeo` composable to access the authentication state and methods such as `getBasicUserInfo`, `signIn`, and `signOut`. It also uses Vue's `ref` to store basic user information and `watch` 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. Errors during user info retrieval are handled by logging them to the console. + +Similarly, you can access other user attributes, such as email, display name, allowed scopes, etc. The following code snippet shows how you can access them in your app. The Asgardeo Vue SDK is responsible for processing the ID token and decoding these attributes. + +```javascript +{% raw %} +

Your email: {{ userInfo?.email }}

+

Display name: {{ userInfo?.displayName }}

+

Allowed scopes: {{ userInfo?.allowedScopes }}

+

Tenant domain: {{ userInfo?.tenantDomain }}

+

Session state: {{ userInfo?.sessionState }}

+{% endraw %} +``` + +## Getting additional user attributes + +Other than the above attributes decoded and available to you by default, the Asgardeo Vue SDK provides the `getDecodedIDToken` 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 in the ID token, the application should be configured to request 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 +{% raw %} + + + +{% endraw %} +``` + +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/vue/assets/img/image7.png){: width="800" style="display: block; margin: 0;"} + +In this step, we further improved our Vue 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/vue/install-asgardeo-sdk.md b/en/asgardeo/docs/complete-guides/vue/install-asgardeo-sdk.md new file mode 100644 index 0000000000..1c163fd998 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/install-asgardeo-sdk.md @@ -0,0 +1,70 @@ +--- +template: templates/complete-guide.html +heading: Install and configure Asgardeo SDK +read_time: 2 min +--- + +## Install @asgardeo/vue + +The Asgardeo Vue SDK is a production-ready SDK that simplifies integrating {{product_name}} as an Identity Provider in your Vue 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. + +!!! Info + + Asgardeo Vue SDK has been developed on open standards such as OAuth2, OpenID Connect, etc., therefore, you can use the Asgardeo Vue 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 Vue SDK from the npm registry. + +```bash +npm install @asgardeo/vue +``` + +## Add Asgardeo Plugin to your Vue app + +During the previous step, we have added the Asgardeo Vue SDK as a dependency in our app. Now, we are going to use the `asgardeoPlugin` from the Asgardeo Vue SDK to integrate authentication into our Vue application. + +First, you need to open the project using an IDE such as VS Code. Then, as shown below, initialize the Asgardeo plugin in `main.ts` or `main.js` with the necessary configuration. Make sure to replace the placeholders with the configuration parameters generated in the {{product_name}} console. + +```javascript +import "./assets/main.css"; + +import { asgardeoPlugin, type AuthVueConfig } from "@asgardeo/vue"; +import { createApp, type App as VueApp } from "vue"; +import App from "./App.vue"; +import router from "./router"; + +const app: VueApp = createApp(App); + +const config = { + signInRedirectURL: "http://localhost:5173", + signOutRedirectURL: "http://localhost:5173", + clientID: "", + baseUrl: "https://api.asgardeo.io/t/", + scope: ["openid", "profile"], +}; + +app.use(router); +app.use(asgardeoPlugin, config); + +app.mount("#app"); +``` + +As shown above, we used `asgardeoPlugin` 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" ]` | + +!!! Info + + 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 Vue 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 `asgardeoPlugin` provides: + +- **Context Management:** It creates a Vue plugin 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:** `asgardeoPlugin` manages user sessions, including token storage and retrieval, token refresh, and user session expiration handling. +- **Easy Access to Authentication:** By using `asgardeoPlugin`, any component within your app can easily access authentication details and actions using Vue composables. +- **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/vue/introduction.md b/en/asgardeo/docs/complete-guides/vue/introduction.md new file mode 100644 index 0000000000..0c44280cd1 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/introduction.md @@ -0,0 +1,40 @@ +--- +template: templates/complete-guide.html +heading: Introduction +read_time: 2 mins +--- +Vue.js is a progressive JavaScript framework designed for building modern single-page applications (SPAs). It enables developers to create dynamic user interfaces by breaking down complex UIs into reusable components. Unlike traditional UI technologies, Vue uses a virtual DOM to efficiently update only the necessary parts of the page without requiring a full re-render. This makes Vue a powerful choice for developing SPAs. + +Implementing login functionality in your Vue app is essential for managing user access, personalizing user experiences, and securing the app. It enhances user experience, protects user data, boosts engagement, and ensures regulatory compliance. + +## Learning objectives + +This guide will walk you through everything you need to know about securing Vue apps, including implementing user login in your Vue app, integrating it with an Identity Provider (IdP) to make the login process simple and secure, and general guidelines to protect your end users. It also covers how to make secure API calls to an OAuth2-protected API within your Vue app. + +In this guide, you will: + +* Register an application in {{product_name}} +* Create a Vue app +* Install Asgardeo Vue SDK +* Add login and logout to your app +* Display logged-in user details +* Secure routes within the app +* Access a protected API from your Vue app +* Manage tokens in your Vue app + + +!!! tip "Tip" + + This guide covers everything required to add user login and secure your Vue apps. If you’re looking for a shorter guide, try the [Vue Quick Start guide](https://is.docs.wso2.com/en/latest/quick-starts/vue/){:target="_blank"}, which takes around 15 minutes to complete. + + +!!! tip "Tip" + + If you are already familiar with the concepts discussed in the guide, you can use the Asgardeo Vue template to bootstrap your application by running the following command. + + ```bash + npx tmplr --dir my-vite-vue-app asgardeo/asgardeo-vite-vue-template + ``` + The Asgardeo Vue template generates a ready-made Vue sample app with pre-configured login and logout capabilities, helping you kick-start your project in just 2 minutes. + + All you need is a `client_id`, which you can obtain by registering a **Single Page Application** in {{product_name}}. \ No newline at end of file diff --git a/en/asgardeo/docs/complete-guides/vue/manage-tokens-in-Vue-apps.md b/en/asgardeo/docs/complete-guides/vue/manage-tokens-in-Vue-apps.md new file mode 100644 index 0000000000..5669d5ad11 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/manage-tokens-in-Vue-apps.md @@ -0,0 +1,115 @@ +--- +template: templates/complete-guide.html +heading: Manage tokens in Vue.js 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 Vue.js 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 Vue.js 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 `config`. + +- **Audience Validation:** The SDK checks the aud (audience) claim to ensure the token is intended for your application (identified by the `clientID` in your `config`). + +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 Vue.js SDK, the state storage mechanism determines where the authentication state, tokens, and other related data are stored. By default, Asgardeo Vue.js 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 config 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 config = { + // 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 config = { + // 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 config = { + // 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 Vue.js 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 config 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 Vue.js 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 `config` 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 Vue.js 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 Vue 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 { useAsgardeo } from "@asgardeo/vue"; + +const config = { + signInRedirectURL: "http://localhost:5173", + signOutRedirectURL: "http://localhost:5173", + clientID: "", + baseUrl: "https://api.asgardeo.io/t/", + scope: ["openid", "profile"], + enableSilentSignIn: true, // Enable silent sign-in +}; + +export default { + setup() { + const { state, signIn } = useAsgardeo(); + + onMounted(() => { + if (!state.value.isAuthenticated) { + signIn({ prompt: "none" }).catch(() => { + // Handle silent sign-in failure + }); + } + }); + + return { state }; + }, +}; +``` diff --git a/en/asgardeo/docs/complete-guides/vue/next-steps.md b/en/asgardeo/docs/complete-guides/vue/next-steps.md new file mode 100644 index 0000000000..f1dc760181 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/next-steps.md @@ -0,0 +1,25 @@ +--- +template: templates/complete-guide.html +heading: Next Steps +read_time: 1 min +--- + +This guide you just have completed, covered the adding user login for Vue.js apps by integrating with an Identity Provider (IdP) and additional use cases such making calls to an OAuth2-protected API. + +!!! tip "Tip" + + As you are now familiar with the concepts discussed in the guide, you can use the Asgardeo Vue template to bootstrap your application by running the following command. + + ```bash + npx tmplr --dir my-vite-vue-app asgardeo/asgardeo-vite-vue-template + ``` + The Asgardeo Vue template generates a ready-made Vue sample app with pre-configured login and logout capabilities, helping you kick-start your project in just 2 minutes. + + All you need is a `client_id`, which you can obtain by registering a **Single Page Application** in {{product_name}}. + +Now that your Vue 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/vue/prerequisite.md b/en/asgardeo/docs/complete-guides/vue/prerequisite.md new file mode 100644 index 0000000000..cd8ce3268b --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/prerequisite.md @@ -0,0 +1,17 @@ +--- +template: templates/complete-guide.html +heading: Prerequisite +read_time: 30 secs +--- + +## Before you start, ensure you have the following: + +* About 60 minutes +* {{product_name}} account +* [Node.js](https://nodejs.org/en/download/package-manager){:target="_blank"} v18+ and npm +* A favorite text editor or IDE + + +!!! 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/vue/register-an-application.md b/en/asgardeo/docs/complete-guides/vue/register-an-application.md new file mode 100644 index 0000000000..7d783e538f --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/register-an-application.md @@ -0,0 +1,38 @@ +--- +template: templates/complete-guide.html +heading: Register an application in Asgardeo +read_time: 1 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 the {{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. + +!!! Example +name: is-vue + + Authorized redirect URL: http://localhost:5173* + +![Register a new application]({{base_path}}/complete-guides/react/assets/img/image8.png){: width="600" style="display: block; margin: 0;"} + +!!! Info + + 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 Vue SDK for the `AsgardeoPlugin` config. + +- Client ID +- Base URL +- Redirect URL + +![Quick start guide]({{base_path}}/complete-guides/vue/assets/img/image9.png){: width="600" style="display: block; margin: 0;"} + +In this step, we've registered our Vue.js app as an application in the {{product_name}} console and generated the required metadata. Next, we will create a Vue app using Vite. diff --git a/en/asgardeo/docs/complete-guides/vue/securing-routes-within-the-app.md b/en/asgardeo/docs/complete-guides/vue/securing-routes-within-the-app.md new file mode 100644 index 0000000000..1e966d5716 --- /dev/null +++ b/en/asgardeo/docs/complete-guides/vue/securing-routes-within-the-app.md @@ -0,0 +1,106 @@ +--- +template: templates/complete-guide.html +heading: Securing Routes within the app +read_time: 2 min +--- + +In a Vue 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 Vue 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 Vue app using [Vue Router](https://router.vuejs.org/){:target="\_blank"}, the official routing library for Vue. + +## Securing Routes with `beforeEnter` + +You can secure routes using the `beforeEnter` navigation guard, ensuring that only authenticated users can access specific routes. + +### Example Implementation + +Below is an example of securing routes using `beforeEnter` with Asgardeo Vue SDK: + +```typescript +import { useAsgardeo, type AuthStateInterface } from "@asgardeo/vue"; +import { + createRouter, + createWebHistory, + type RouteLocationNormalized, + type NavigationGuardNext, + type Router, +} from "vue-router"; +import HomeView from "../views/HomeView.vue"; +import LandingView from "@/views/LandingView.vue"; +import { watch } from "vue"; + +const router: Router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + component: LandingView, + name: "landing", + path: "/", + }, + { + beforeEnter: async (to: RouteLocationNormalized, from: RouteLocationNormalized) => { + const { state, isAuthenticated, signIn } = useAsgardeo(); + + // Wait for loading to complete if still in progress + if (state.isLoading) { + await waitForAsgardeoLoaded(state); + } + + try { + const auth = await isAuthenticated(); + if (!auth) { + await signIn(); + return false; // Prevent navigation until sign-in completes + } + return true; + } catch { + return false; // Prevent navigation on error + } + }, + component: HomeView, + name: "home", + path: "/home", + }, + ], +}); + +/** + * Wait for Asgardeo loading state to complete before proceeding + * @param state - The Asgardeo state containing isLoading property + * @returns A promise that resolves when loading is complete + */ +async function waitForAsgardeoLoaded(state: AuthStateInterface) { + return new Promise((resolve) => { + // If already not loading, resolve immediately + if (!state.isLoading) { + resolve(); + return; + } + + // Watch for changes in loading state + const unwatch = watch( + () => state.isLoading, + (isLoading) => { + if (!isLoading) { + unwatch(); + resolve(); + } + }, + ); + }); +} + +export default router; +``` + +## How it Works + +1. `beforeEnter` is used as a navigation guard on protected routes. +2. It checks the Asgardeo authentication state before allowing access. +3. If the user is not authenticated, they are redirected to the login flow. +4. The `waitForAsgardeoLoaded` function ensures that authentication state is checked only after Asgardeo has completed loading. + +This method provides a flexible and robust way to protect routes while leveraging Asgardeo Vue SDK’s capabilities. + +Next, we will explore how to access a protected API from our Vue app, a common requirement for SPAs. + diff --git a/en/asgardeo/mkdocs.yml b/en/asgardeo/mkdocs.yml index 6b0ccdf39f..c0ae9ff65e 100644 --- a/en/asgardeo/mkdocs.yml +++ b/en/asgardeo/mkdocs.yml @@ -635,6 +635,18 @@ nav: - Accessing protected API : complete-guides/angular/accessing-protected-api.md - Manage tokens in Angular : complete-guides/angular/manage-tokens.md - Next Steps: complete-guides/angular/next-steps.md + - Vue: + - Introduction: complete-guides/vue/introduction.md + - Prerequisite: complete-guides/vue/prerequisite.md + - Configure an application: complete-guides/vue/register-an-application.md + - Create a Vue app: complete-guides/vue/create-a-vue-app.md + - Configure Asgardeo SDK: complete-guides/vue/install-asgardeo-sdk.md + - Add login and logout: complete-guides/vue/add-login-and-logout.md + - Display user details: complete-guides/vue/display-logged-in-user-details.md + - Securing Routes: complete-guides/vue/securing-routes-within-the-app.md + - Accessing protected API: complete-guides/vue/accessing-protected-api.md + - Manage tokens in Vue: complete-guides/vue/manage-tokens-in-Vue-apps.md + - Next Steps: complete-guides/vue/next-steps.md - Javascript: - Introduction: complete-guides/javascript/introduction.md - Prerequisite: complete-guides/javascript/prerequisite.md diff --git a/en/base.yml b/en/base.yml index 11cef3a547..8f55bbf19e 100644 --- a/en/base.yml +++ b/en/base.yml @@ -125,6 +125,9 @@ extra: Angular: link: complete-guides/angular/introduction level: 2 + Vue: + link: complete-guides/vue/introduction + level: 2 Node.js: link: complete-guides/nodejs/introduction level: 2 @@ -195,6 +198,9 @@ extra: Angular: icon: fontawesome/brands/angular level: 2 + Vue: + icon: fontawesome/brands/vuejs + level: 2 Javascript: icon: fontawesome/brands/js level: 2