S
S
survivor20052021-09-16 13:08:42
Vue.js
survivor2005, 2021-09-16 13:08:42

I don't understand how router.beforeEach works in vue?

Good afternoon, I'm trying to make authentication in view + lara using Rest api.
In general, the logic is this, when going to any page, we check if there is a key with an identifier in localstorage, if not, then go to /login, if there is, then the identifier is checked on the server, if everything is OK, we go to the desired page.
Read how hooks work. From what I've read, I'm trying to do something like this:

import { createRouter, createWebHistory } from 'vue-router'
import Logon from '@/Logon.vue'
import Projects from '@/views/Projects.vue'
import Homepage from '@/views/Homepage.vue'
import Project from '@/views/Project.vue'
import Control from '@/views/Control.vue'
import ControlUsers from '@/views/Control-users.vue'

const routes = [
  {
    path: '/logon',
    name: 'Logon',
    component: Logon
  },
  {
    path: '/',
    name: 'Homepage',
    component: Homepage
  },
  {
    path: '/projects',
    name: 'Projects',
    component: Projects
  },
  {
    path: '/project',
    name: 'Project',
    component: Project
  },
  {
    path: '/control',
    name: 'control',
    component: Control
  },
  {
    path: '/control/control-users',
    name: 'control-users',
    component: ControlUsers
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

router.beforeEach((to, from, next) => {
  if (to.name !== 'Logon' && !localStorage.getItem('authToken')) {
    next({ name: 'Logon' })
  } else next()
})

router.beforeEach((to, from, next) => {
  if (to.name !== 'Logon' && localStorage.getItem('authToken')) {
    next({ name: 'Homepage' }) //тут будет логика проверки токена на сервере
  } else next()
})

export default router


The first hook works and sends me to log in, then I log in, I get a biar token in localstorage. But the second hook does not work, although if you output something to the console there, then it is displayed, that is, the hook actually works, but it does not redirect me to the main page.
And in general, the hook itself works somehow strangely, for example, I tried to do this:
router.beforeEach((to, from, next) => {
  if (!localStorage.getItem('authToken')) {
    next({ name: 'Logon' })
  } else next()
})
\\ а второй хук я убрал, и так тоже у меня не работает, по логике должно же если в if true, то выполни \\ условие, что ему не нравится в этом условии я не понимаю. Даже если напишу вот так:
const isAuth = false
router.beforeEach((to, from, next) => {
  if (!isAuth)) {
    next({ name: 'Logon' })
  } else next()
})
Это тоже не работает, даже ошибки не выводит тупо останавливает загрузку контента? если жму на ссылки в хедере то выходят ошибки:
Uncaught (in promise) Error: Infinite redirect in navigation guard
    at eval (vue-router.esm-bundler.js?6c02:2991)

I know I'm doing something wrong, but I can't figure out what.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
survivor2005, 2021-09-17
@survivor2005

This may be useful to someone, the solution is not ideal, but it works:

import { createRouter, createWebHistory } from 'vue-router'
import Logon from '@/Logon.vue'
import Projects from '@/views/Projects.vue'
import Homepage from '@/views/Homepage.vue'
import Project from '@/views/Project.vue'
import Control from '@/views/Control.vue'
import ControlUsers from '@/views/Control-users.vue'

const routes = [
  {
    path: '/logon',
    name: 'Logon',
    component: Logon
  },
  {
    path: '/',
    name: 'Homepage',
    component: Homepage
  },
  {
    path: '/projects',
    name: 'Projects',
    component: Projects
  },
  {
    path: '/project',
    name: 'Project',
    component: Project
  },
  {
    path: '/control',
    name: 'control',
    component: Control
  },
  {
    path: '/control/control-users',
    name: 'control-users',
    component: ControlUsers
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

let isAuth = false

router.beforeEach((to, from, next) => {
  if (to.name !== 'Logon' && !localStorage.getItem('authToken')) {
    next({ name: 'Logon' })
  } else next()
})

router.beforeEach(async (to, from, next) => {
  if (localStorage.getItem('authToken') && !isAuth && to.name !== 'Logon') {
    const request = await fetch('http://localhost:8000/api/authuser', {
      method: 'POST',
      credentials: 'same-origin',
      headers: {
        'Content-type': 'application/json',
        Authorization: localStorage.getItem('authToken')
      }
    })
    const response = await request
    if (response.status === 200) {
      isAuth = true
      next(to.fullPath)
    } else next({ name: 'Logon' })
  } else next()
})

export default router

A
Andrew, 2021-09-16
@AndrewRusinas

I think that beforeEach cannot take several functions in itself in this way. Most likely, only one of them is recorded and worked out. We need to combine all the logic into one method. Also, you can use hooks for each specific route using the beforeEnter key. By default, it is also possible to call only one method there, but using the multigard plugin, it will be possible to hang several handlers at the same time.

L
low molecular macro, 2021-09-17
@molekulyarniy

I read issues for vue-router on github, and I can say: the use of several identical hooks is not supported. And they are not going to introduce such a chip in the future, because. it's redundant. If you are interested, you can read for yourself. There is also a solution that replaces the use of multiple beforeEach hooks

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question