N
Nuxt2y ago
Sumit

Reload During Mounting

I am trying to load a few components conditionally. Here is the code snippet.
// app.vue
<template>
<div v-if="isLoggedIn">
<NuxtPage />
</div>
<div v-else-if="unauthorized">
<ErrorCard :error-status="403" :error-desc="$t('not-a-valid-azure-group-member')" />
</div>
</template>

<script setup lang='ts'>
import { useAuthStore } from '~/store/auth'
let unauthorized = ref(false)
let isLoggedIn = ref(false);
await getToken()
const currentUser = useAuthStore()
if (!currentUser.loggedIn) {
unauthorized.value = true
} else {
isLoggedIn.value = true;
}
await signIn()
</script>
// app.vue
<template>
<div v-if="isLoggedIn">
<NuxtPage />
</div>
<div v-else-if="unauthorized">
<ErrorCard :error-status="403" :error-desc="$t('not-a-valid-azure-group-member')" />
</div>
</template>

<script setup lang='ts'>
import { useAuthStore } from '~/store/auth'
let unauthorized = ref(false)
let isLoggedIn = ref(false);
await getToken()
const currentUser = useAuthStore()
if (!currentUser.loggedIn) {
unauthorized.value = true
} else {
isLoggedIn.value = true;
}
await signIn()
</script>
I expect the above code to show <NuxtPage /> when the user is logged in and the error component only when the user is unauthorized. But, when we load the app for the first time by visiting localhost:3000, it briefly shows the error component and then refreshes to show the NuxtPage. I am not able to figure out what's wrong with the code. Any help will be highly appreciated. PS. The login system is using Microsoft Authentication Library (MSAL). getToken fetches a token and saves it in AuthStore which is then fetched using useAuthStore. MSAL works by redirecting to a Microsoft Authentication Portal and then if the token is already present for the user (already signed in), redirects back to the site, or if the token is not already present then keeps the user on its authentication portal until the user completes signing in.
5 Replies
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Sumit
Sumit2y ago
Thanks for the response Chris. Here is what getToken and signIn methods contain.
// signIn.ts
export const signIn = async () => {
const { $msal } = useNuxtApp()
const runtimeConfig = useRuntimeConfig()
const loginRequest = {
scopes: [runtimeConfig.public.scopes]
}
if (typeof $msal !== 'undefined') {
function handleResponse (response: any) {
if (response !== null) {
} else {
const currentAccounts = $msal.getAllAccounts()
if (currentAccounts.length === 0) {
$msal.loginRedirect(loginRequest)
} else if (currentAccounts.length > 0) {
}
}
}
try {
const response = await $msal.handleRedirectPromise()
handleResponse(response)
} catch (err) {
console.error('MSAL err: ', err)
}
}
}
// signIn.ts
export const signIn = async () => {
const { $msal } = useNuxtApp()
const runtimeConfig = useRuntimeConfig()
const loginRequest = {
scopes: [runtimeConfig.public.scopes]
}
if (typeof $msal !== 'undefined') {
function handleResponse (response: any) {
if (response !== null) {
} else {
const currentAccounts = $msal.getAllAccounts()
if (currentAccounts.length === 0) {
$msal.loginRedirect(loginRequest)
} else if (currentAccounts.length > 0) {
}
}
}
try {
const response = await $msal.handleRedirectPromise()
handleResponse(response)
} catch (err) {
console.error('MSAL err: ', err)
}
}
}
// getToken.ts
import { InteractionRequiredAuthError } from '@azure/msal-browser'
import jwtDecode from 'jwt-decode'
import { useAuthStore } from '~/store/auth'

export const getToken = async () => {
const authStore = useAuthStore()
const { $msal } = useNuxtApp()
const runtimeConfig = useRuntimeConfig()
if (typeof $msal !== 'undefined') {
const redirectResponse = await $msal.handleRedirectPromise()
if (redirectResponse !== null) {
const accessToken = redirectResponse.accessToken
if (accessToken !== null) {
const isMember = await checkGroupMembership(accessToken, runtimeConfig.public.appGroupId)
if (isMember) {
authStore.updateCurrentUser(accessToken)
} else {
throw new Error('User is not a member of the required group.')
}
}
} else {
const account = $msal.getAllAccounts()[0]
const accessTokenRequest = {
scopes: [runtimeConfig.public.scopes],
account
}
try {
const accessTokenResponse = await $msal.acquireTokenSilent(
accessTokenRequest
)
const accessToken = accessTokenResponse.accessToken
if (accessToken !== null) {
const isMember = await checkGroupMembership(accessToken, runtimeConfig.public.appGroupId)
if (isMember) {
authStore.updateCurrentUser(accessToken)
} else {
throw new Error('User is not a member of the required group.')
}
}
} catch (error) {
console.error(error)
if (error instanceof InteractionRequiredAuthError) {
$msal.acquireTokenRedirect(accessTokenRequest)
}
}
}
}
}
.
.
.
// getToken.ts
import { InteractionRequiredAuthError } from '@azure/msal-browser'
import jwtDecode from 'jwt-decode'
import { useAuthStore } from '~/store/auth'

export const getToken = async () => {
const authStore = useAuthStore()
const { $msal } = useNuxtApp()
const runtimeConfig = useRuntimeConfig()
if (typeof $msal !== 'undefined') {
const redirectResponse = await $msal.handleRedirectPromise()
if (redirectResponse !== null) {
const accessToken = redirectResponse.accessToken
if (accessToken !== null) {
const isMember = await checkGroupMembership(accessToken, runtimeConfig.public.appGroupId)
if (isMember) {
authStore.updateCurrentUser(accessToken)
} else {
throw new Error('User is not a member of the required group.')
}
}
} else {
const account = $msal.getAllAccounts()[0]
const accessTokenRequest = {
scopes: [runtimeConfig.public.scopes],
account
}
try {
const accessTokenResponse = await $msal.acquireTokenSilent(
accessTokenRequest
)
const accessToken = accessTokenResponse.accessToken
if (accessToken !== null) {
const isMember = await checkGroupMembership(accessToken, runtimeConfig.public.appGroupId)
if (isMember) {
authStore.updateCurrentUser(accessToken)
} else {
throw new Error('User is not a member of the required group.')
}
}
} catch (error) {
console.error(error)
if (error instanceof InteractionRequiredAuthError) {
$msal.acquireTokenRedirect(accessTokenRequest)
}
}
}
}
}
.
.
.
// getToken.ts
.
.
.
interface CustomJwtPayload {
groups?: string[];
}

const checkGroupMembership = async (accessToken: string, groupId: string): Promise<boolean> => {
const decodedToken = await jwtDecode(accessToken) as CustomJwtPayload
const groups = decodedToken?.groups
if (!groups || !Array.isArray(groups)) {
throw new Error('Groups claim not found in token.')
}
return groups.includes(groupId)
}
// getToken.ts
.
.
.
interface CustomJwtPayload {
groups?: string[];
}

const checkGroupMembership = async (accessToken: string, groupId: string): Promise<boolean> => {
const decodedToken = await jwtDecode(accessToken) as CustomJwtPayload
const groups = decodedToken?.groups
if (!groups || !Array.isArray(groups)) {
throw new Error('Groups claim not found in token.')
}
return groups.includes(groupId)
}
I tried with the code snipped that you've suggested @chris.foss but the problem persists.
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Sumit
Sumit2y ago
Thanks for taking another look @chris.foss . I tried making handleResponse async and awaiting handleResponse and $msal.loginRedirect. But the problem still persists.
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Want results from more Discord servers?
Add your server