andreybold
@andreybold

Как правильно получить токен перед загрузкой приложения?

Суть в следующем: есть приложение на Vue3.
В корневом компоненте, нужно проверить токен из localStorage.
Если его там нет, то отправить на страницу логина.
Если он там есть, то обратиться к API для того, чтобы проверить акуальность токена.
Если он акуален, то загрузить главную страницу приложения. Если не актуален, то так же отправить на страницу логина.

Проблема в том, что если проверку токена через API положить в beforeMount или другие похожие хуки, то если обновить страницу (или зайти на неё), то есть вероятность получить ошибку авторизации, т.к. токен ещё не проверился, а дочерние компоненты уже подгрузились и пытаются к своим точкам в API достучаться, с пустым токеном.
Если же попробовать проверку запихать в setup, то там та же проблема. При этом если setup сделать async, то приложение не грузится. Про suspense читал, но не до конца понял как оно работает.
Сейчас пока остановился на следующем коде (код пока не рабочий):
export default {
	async setup() {
		const store = useStore();

		let localToken = localStorage.getItem('token');
		let isLogined = false;

		if(localToken) {
			await checkToken(localToken).then(response => {
				if(response.data?.check) {
					isLogined = true;
					store.setToken(localToken);
				}
			});
		}

		return { store, localToken, isLogined }
	},
	beforeMount() {
		if(!this.localToken || !this.isLogined) {
			this.$router.push({ name: 'login' })
		}

		if(this.store.getToken() && this.$route.name == 'login') {
			this.$router.push({ name: 'notices.list' });
			isLogined = true;
		}

		if(this.store.getToken() && this.isLogined) {
			this.store.reloadPages();
			this.store.loadBlockTypes();
		}
	}
}
  • Вопрос задан
  • 158 просмотров
Решения вопроса 2
@maximabro
frontend developer
Можно сделать через хук роутера BeforeEach. В этом хуке делать проверку токена и если нет токена, то перенаправлять на страницу auth.

Вот пример мой, как я это делаю
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
    {
      path: "/",
      name: "home",
      component: home,
      meta: {
        auth: true,
      },
    },
    {
      path: "/auth",
      name: "auth",
      component: () => import("@/views/auth.vue"),
    },
  ],
})

router.beforeEach(async (to, from, next)=> {
  if (to.meta.auth) {
    const result = await http.get("/auth/check");
    if (result.data.message === "ok") {
      next()
    } else {
      next("/auth");
    }
  }
});

export default router;


Также в этом хуке можно использовать стейт менеджер.
Ответ написан
Комментировать
wapster92
@wapster92 Куратор тега JavaScript
Не перекладывать работу с токенами на vue, а создать слой по работе с ними. Один из самых удобных вариантов использовать инстансы axios
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы