Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

cjholowatyj's avatar

Testing authentication immediately after login in Vue

I have this infuriating bug I'm trying to solve, whereby a script that runs in the onMounted lifecycle hook of my admin dashboard page in Vue triggers an authenticated user check on the user state BEFORE the onSuccess hook from the login form completes, which is where I update the user state in Pinia.

This bug results in the admin dashboard being flashed to the (admin) user for only a split second before being kicked off to the homepage (which I only want to happen if the user is indeed not an admin and not authenticated as such ~ a check that should fail if the user just logged in successfully as an admin!).

Here's a sample excerpt from my the script tag of my Vue layout page for all admin pages:

import {useUserStore} from '@flighter/stores';
import {type Pinia} from 'pinia';

const pinia = inject('globalPinia') as Pinia;
const $ = {u: () => useUserStore(pinia)};

const props = defineProps({
	allowGuests: {type: Boolean, default: false}
});

onMounted(() => {
	if (!props.allowGuests && !$.u().authenticated) {
		console.log('Should redirect to guest page', $.u().user);
		//router.get('/', {});
	} else {
		console.log('Should not redirect to guest page', $.u().user);
	}
});

It's commented out for now, but when I uncomment the call to router, it redirects any recently logged in user (regardless of their type) to the homepage, because the user state isn't updated quick enough...

Is there a way to update the state of the user store before the new page is mounted after a successful login attempt?

Or is there a better way to handle user state updating after a successful login attempt that prevents this type of issue?

I'm working with Laravel 10 +Octane/InertiaJS +SSR/Vue 3 +CompAPI/Vite 4/Pinia

0 likes
2 replies
LaryAI's avatar
Level 58

To address the issue of the user state not being updated quickly enough after a successful login, you can consider a few strategies to ensure that the authentication state is correctly set before the admin dashboard page is mounted. Here are some potential solutions:

  1. Use a Promise or Async/Await for State Update: Ensure that the login process, including the state update, is completed before navigating to the admin dashboard. You can achieve this by using promises or async/await to handle the login process.

  2. Route Guards: Implement route guards to check the authentication state before allowing access to the admin dashboard. This way, the navigation to the admin page will only occur if the user is authenticated.

  3. Event Bus or Emit Events: Use an event bus or emit events to notify the admin dashboard component when the user state has been updated. This can help in delaying the execution of the onMounted logic until the user state is confirmed.

Here's an example of how you might implement a route guard in Vue Router to ensure the user is authenticated before accessing the admin dashboard:

  1. Delay the onMounted Logic: You can delay the execution of the onMounted logic until the user state is confirmed. This can be done by using a watcher on the authenticated state or by using a setTimeout as a temporary workaround.
import { watch } from 'vue';
import { useUserStore } from '@flighter/stores';

onMounted(() => {
  const userStore = useUserStore();

  watch(
    () => userStore.authenticated,
    (isAuthenticated) => {
      if (!props.allowGuests && !isAuthenticated) {
        console.log('Should redirect to guest page', userStore.user);
        // router.push('/');
      } else {
        console.log('Should not redirect to guest page', userStore.user);
      }
    },
    { immediate: true }
  );
});

By implementing one or a combination of these strategies, you should be able to ensure that the user state is correctly updated before the admin dashboard is accessed, preventing the unwanted redirection.

MaverickChan's avatar

onMounted could be async function .

onMounted(async () => {
	await checkLoginStatus()
	//do other stuff.
})

btw, you should check login status in the state check function in global state there.

Please or to participate in this conversation.