How to autologin an user if he's already logged in

Viewed 420

This works for me if the user isn't logged in, however the else if wont work at all even though the route path is "/login" and main.authState is true. How do I set this up properly?


router.beforeEach((to, from, next) => {
  const main = useAuthStore(router.pinia);

  if (to.matched.some((record) => record.meta.authRequired)) {
    if (!main.authState) {
      return next("/login");
    }
  } else if(to.matched.some((record) => !record.meta.authRequired)) {
    if (to.path == "/login" && main.authState == true) {
      alert(to.path) //"/login"
      alert(typeof(main.authState)) //"boolean"
      return next();
    }
  }
  next();
});
    async signOut() {
      await auth.logout();
      await localStorage.removeItem("authenticated");
      await router.replace({ name: "Login" });
    },
2 Answers

If auth is not required for some route, you should not check for authState. If I didn't understand correctly, explain.

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.authRequired)) {
    const { authState } = useAuthStore(router.pinia);
   // Ensure what authState is true to proceed to next() route  

    authState
      ? next()
      : next('/login');
  } else {
    next();
  }
});

You could use a URL query param to store the redirect target, which you then access from your Login.vue component, and can set a default value to redirect to when the user accesses the /login route as an authenticated user without a predefined redirect.

router.beforeResolve(async (to, from, next) => {
  if (to.matched.some((record) => record.meta.authRequired)) {
    const lastMathcedRoute = to.matched[to.matched.length - 1].path || "/";
    // "/" is just a fallback route
    const main = useAuthStore(router.pinia);
    const isAuthenticated = main.authState;

    if (!isAuthenticated ) {
      next({ path: "/login", query: { redirect: lastMathcedRoute } });
    } else {
      next();
    }
  } else {
    next();
  }
});

And then in your Login component, you just access the redirect query param if user is already authenticated or when his auth state changes. Basically you need to somehow be notified, or watch the auth state and redirect the user accordingly. So you need authState to be a ref or reactive object that you can watch.

// Login.vue
import { useRouter } from "vue-router";

setup() {
  const router = useRouter();
  const { authState } = useAuthStore(router.pinia);

  watch(authState, () => {
    if (authState) {
      const redirectLocation = route.query?.redirect?.toString() || '/pannel'; 
      // here '/panel' is the default redirect
      return router.push(redirectLocation);
    }
  }, { immediate: true } )

}

PRO Tip: notice { immediate: true }, this makes it so that the watch immediately fires with the initial value of the authState, instead of firing just when it changes. This is helpful in the case that the authState is already true and it does not change.

You can use other mechanisms instead of a watcher, but in principle the solution is the same.

Related