@survivor2005

Не понимаю как работает router.beforeEach во vue?

Доброго дня, пытаюсь сделать аутентификацию во вью + лара по Rest api.
В общем логика такая, при переходе на любую страницу проверяем есть ли в localstorage ключь с идентификатором, если нет то шли на /login, если есть то идет проверка идентификатора на сервере, если все ок переходим на желаемую страницу.
Почитал как работают хуки. Из прочитанного пытаюсь сделать что то типа такого:
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


Первый хук отрабатывает и шлет меня залогиниться, далее я логинюсь у меня появляется в localstorage биар токен. Но второй хук не работает, хотя если там вывести что то в консоль то это выводится, то есть хук срабатывает по сути, но вот не пересылает меня на главную страницу.
И вообще как то странно работает хук сам по себе, например я попробовал сделать так :
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)

Я понимаю что делаю что то не так, но что не могу понять.
  • Вопрос задан
  • 109 просмотров
Решения вопроса 1
@survivor2005 Автор вопроса
Вот может кому пригодиться, решение не идеальное, но работает:
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
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@AndrewRusinas
Я думаю, что beforeEach не может в себя принимать таким образом несколько функций. Скорее всего, записывается и отрабатывает только одна из них. Нужно объединить всю логику в один метод. Так же, вы можете использовать хуки для каждого конкретного роута, используя ключ beforeEnter. По умолчанию там точно так же возможен вызов только одного метода, но с помощью плагина multigard можно будет навешивать несколько обработчиков одновременно.
Ответ написан
Читал issues к vue-router на гитхабе, и могу сказать: использование нескольких одинаковых хуков не поддерживается. И вводить такую фишку в будущем не собираются, т.к. это избыточно. Если интересно, можете почитать сами. Там есть и решение, которое заменяет использование нескольких beforeEach хуков
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
28 окт. 2021, в 05:45
1000 руб./за проект
28 окт. 2021, в 04:48
1200 руб./за проект
28 окт. 2021, в 03:00
500000 руб./за проект