Vue. js: Как защитить компонент входа в систему от аутентифицированного пользователя - PullRequest
0 голосов
/ 06 февраля 2020

Я разрабатываю приложение, в котором аутентификация реализована с использованием firebase-auth. Я уже защитил пользовательский компонент от неаутентифицированных пользователей. Но теперь я хочу защитить компонент входа в систему от аутентифицированных пользователей. Я пробовал это до сих пор. Вот мой роутер / индекс. js

import Vue from 'vue'
import VueRouter from 'vue-router'
import {
  fb
} from "@/firebase/init";
import Home from '@/views/Home'

Vue.use(VueRouter)

const routes = [{
    path: '/',
    name: "home",
    component: Home
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/components/auth/Login'),
    meta: {
      alreadyAuth: true
    }
  },
  {
    path: '/signup',
    name: 'signup',
    component: () => import('@/components/auth/Signup'),

  },
  {
    path: '/user/:id',
    name: 'user',
    component: () => import('@/components/user/User'),
    meta: {
      requiresAuth: true
    }
  },

]

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

router.beforeEach((to, from, next) => {
  let user = fb.auth().currentUser
  if (to.matched.some(rec => rec.meta.requiresAuth)) {
    if (user) {
      next()
    } else {
      next({
        name: 'login'
      })
    }
  } else if (to.matched.some(rec => rec.meta.alreadyAuth)) {
    if (user) {
      next({
        name: 'user'
      })
    } else {
      next()
    }
  } else {
    next()
  }
})

export default router

И еще одна проблема заключается в том, что когда я аутентифицируюсь и обновляю sh пользовательский компонент, он перенаправляет меня обратно на компонент входа в систему. Почему так?

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Поскольку я не знаю ваш main.js, это всего лишь предположение, но я думаю, currentUser - это undefined. Вы должны войти user и проверить, определено ли это при загрузке страницы. Firebase действует асинхронно c, поэтому для того, чтобы все подготовить, вам нужно обернуть все приложение в обратный вызов Firebase.

firebase.auth().onAuthStateChanged(() => {
    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app');
});

В противном случае currentUser, вероятно, еще не инициализировано.

0 голосов
/ 06 февраля 2020

Таким образом, вы хотите запретить вошедшим в систему пользователям доступ к вашему маршруту входа, но вы также хотите, чтобы не зарегистрированные пользователи не заходили на определенные страницы в вашем приложении Vue. Довольно стандартный вариант использования. Вот как я это реализовал:

Во-первых, у моих маршрутов есть метатеги requiresAuth и forVisitors. Если пользователь вошел в систему и попытался перейти по маршруту forVisitors, я возвращаю его на домашнюю страницу (routeObject.path = '/' в моем примере ниже). Если пользователь не вошел в систему и пытается найти путь requiresAuth, я выгоняю его в / login. Я обнаружил, что этот подход довольно гибок для построения маршрута.

Мой маршрутизатор должен знать, что входит в систему вошедшего в систему пользователя. Используя модуль авторизации Firebase, я могу подписаться на onAuthStateChanged и выяснить, вошел ли пользователь в систему с первого выпуска.

Обратите внимание, я сохраняю текущего пользователя в хранилище VueX (store.state.userModule.user), вы можете игнорировать этот бит, если вы этого не сделаете. Кроме того, я храню объект Firebase Auth в своем магазине как store.state.userModule.auth, поэтому, когда вы видите это, он аналогичен Firebase auth.

Кроме того, вы можете найти более подробную информацию о том, почему я заключаю мою подписку onAuthStateChanged в Обещание здесь: Получение 'Uncaught' после обнаружения ошибки в firebase.auth () с asyn c


const router = new Router({
    /* example of forVisitors path */
    {
        path: '/Login',
        name: 'Login',
        component: Login,
        meta: {
            requiresAuth: false,
            forVisitors: true
        }
    },
    /* example of requiresAuth path */
    {
        path: '/Submit/:mode?/:primary?/:secondary?',
        name: 'Submit',
        component: Submit,
        props: true,
        meta: {
            requiresAuth: true
        }
    }
});

router.beforeEach(async (to, from, next) => {
/* Check for a user in my store, or fallback to Firebase auth() user */
    let currentUser =
        store.state.userModule.user ||
        (await new Promise((resolve) => {
            store.state.userModule.auth().onAuthStateChanged(user => {
                resolve(user);
            });
        }));

    const requiresAuth = to.meta.requiresAuth;
    const forVisitors = to.meta.forVisitors;
    const routeObject = {};

    if (forVisitors && currentUser) {
        routeObject.path = '/';
    } else if (requiresAuth && !currentUser) {
        routeObject.path = '/login';
    }

    next(routeObject);
});
...