Skip to content

Add Vue.js Complete guide to asgardeo-docs #5211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions en/asgardeo/docs/complete-guides/vue/accessing-protected-api.md
Original file line number Diff line number Diff line change
@@ -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/<org_name>/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 <access_token_retrieved_from_web_worker>",
},
method: "GET",
url: "https://api.asgardeo.io/t/<org_name>/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/<org_name>/scim2/me",
{
headers: {
Authorization: "Bearer " + accessToken,
},
}
);
console.log(response);
})
.catch((error) => {
console.log(error);
});
});
},
};
```
77 changes: 77 additions & 0 deletions en/asgardeo/docs/complete-guides/vue/add-login-and-logout.md
Original file line number Diff line number Diff line change
@@ -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
<script setup lang="ts">
import { useAsgardeo } from "@asgardeo/vue";

const { signIn, signOut, state } = useAsgardeo();
</script>

<template>
<div>
<div v-if="state.isAuthenticated">
<button @click="signOut">Logout</button>
</div>
<div v-else>
<button @click="signIn">Login</button>
</div>
</div>
</template>
```

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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions en/asgardeo/docs/complete-guides/vue/create-a-vue-app.md
Original file line number Diff line number Diff line change
@@ -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.
145 changes: 145 additions & 0 deletions en/asgardeo/docs/complete-guides/vue/display-logged-in-user-details.md
Original file line number Diff line number Diff line change
@@ -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 %}
<script setup lang="ts">
import { useAsgardeo } from "@asgardeo/vue";

const auth = useAsgardeo();
const { signIn, signOut, state } = auth;
</script>

<template>
<div>
<div v-if="state.isAuthenticated">
<p>Welcome, {{ state.username }}</p>
<button @click="signOut">Logout</button>
</div>
<div v-else>
<button @click="signIn">Login</button>
</div>
</div>
</template>
{% 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 %}
<script setup lang="ts">
import { useAsgardeo } from "@asgardeo/vue";
import { ref, watch } from "vue";

const auth = useAsgardeo();
const { signIn, signOut, state, getBasicUserInfo } = auth;
const userInfo = ref(null);

watch(
() => state.isAuthenticated,
async (isAuthenticated) => {
if (isAuthenticated) {
try {
userInfo.value = await getBasicUserInfo();
} catch (error) {
console.error(error);
}
}
},
{ immediate: true }
);
</script>

<template>
<div>
<div v-if="state.isAuthenticated">
<p>Welcome, {{ userInfo?.username }}</p>
<button @click="signOut">Logout</button>
</div>
<div v-else>
<button @click="signIn">Login</button>
</div>
</div>
</template>
{% 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 %}
<p>Your email: {{ userInfo?.email }}</p>
<p>Display name: {{ userInfo?.displayName }}</p>
<p>Allowed scopes: {{ userInfo?.allowedScopes }}</p>
<p>Tenant domain: {{ userInfo?.tenantDomain }}</p>
<p>Session state: {{ userInfo?.sessionState }}</p>
{% 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 %}
<script setup lang="ts">
import { useAsgardeo } from "@asgardeo/vue";
import { ref, watch } from "vue";

const auth = useAsgardeo();
const { signIn, signOut, state, getDecodedIDToken } = auth;

const mobileNumber = ref("");

watch(
() => state.isAuthenticated,
async (isAuthenticated) => {
if (isAuthenticated) {
try {
const decodedIdToken = await getDecodedIDToken();
console.log(decodedIdToken);
mobileNumber.value = decodedIdToken.phone_number;
} catch (error) {
console.error(error);
}
}
},
{ immediate: true }
);
</script>

<template>
<div>
<p>Your mobile number: {{ mobileNumber }}</p>
</div>
</template>
{% 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.
Loading