Vin
Vin

Reputation: 169

How to implement vue-guards beforeEach properly to for authentication

Why my code directly goes to my else statement even though I followed the documentation in vue-router?

It directly goes to my else statement "Not even a match". It should print "Found a match".

Did I miss something here?

const routes = [
  {
    path: "/login",
    name: "login",
    component: () => import("../views/vLogin.vue")
  },
  {
    path: "/",
    name: "Article",
    component: () => import("@/views/articles/vArticleManage"),
    meta: {
      requiresAuth: true
    }
  }
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes
});

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    console.log("Found a match")
    let sampleAuth = true;
    if(sampleAuth) {
      next();
    } else{
      next({
       path: "/login",
        query: {
          redirect: to.fullPath
        }
      })
    }
  } else {
    console.log("Not even a match")
  }
})
export default router;

p.s Here is the image when I tried to log the "to" image

Upvotes: 1

Views: 674

Answers (1)

Marc
Marc

Reputation: 5465

I too initially followed that suggestion from the documentation and had no success with it.

Instead I now use router.beforeResolve((to, from, next) which fires much later (fires the latest) in the logic.

beforeEach fires very early where I found it result in a much higher chance of creating code execution race condition issues in navigation guards as if something has not had time to initialize or not had chance to set an expected state.

There is also router.beforeEnter that fires a little before beforeResolve but way later than beforeEach.

I have 5 major VUE projects, so far am not sure what the actual use of beforeEach is since anything I have tried has not worked with it.

Hint: I always return void after calling next() to ensure further logic is not executed after and is much cleaner than if/else statements especially if there is a lot of if statements.

I am not sure about the usage of to.matched.some as everything I have built is predictable exact match so I actually use:

Object.prototype.hasOwnProperty.call(to.meta, 'requiresAuth')

router.beforeResolve((to, from, next) => {

  if (Object.prototype.hasOwnProperty.call(to.meta, 'requiresAuth')) {

    console.log("Found a match")

    let sampleAuth = true;

    if(sampleAuth) {

      next();
      return;

    }

    next({
      name: 'login', // <-- Login route has a name, use that reference instead.
      query: {
        redirect: to.fullPath
      }
    })

    return;

  }

  console.log("Not even a match")

})

Hint: Object.prototype.hasOwnProperty.call(...) while ugly, is more secure and reliable than myVar.hasOwnProperty(...) Read More

Upvotes: 2

Related Questions