0

I've implemented Firebase (aka. Google Identity Platform) into my Vue project. I want to protect specific routes, so I've added the following:

// router/index.js

    {
        path: '/profile',
        name: 'Profile',
        component: Profile,
        beforeEnter: (to, from, next) => {
            if (firebase.auth().currentUser) {
                next()
            } else {
                next({
                    path: '/login',
                })
            }
        }
    },

This works! However, it would become unmanageable if I did that for every route.

To make it tidy, I tried putting it into a function (within the route file and tried externally) but it won't work because Firebase hasn't been initialized at the time it is parsed so it throws an error saying to initialize Firebase first.

Firebase is initialised in my main.js file:

// main.js

// Firebase configuration
var firebaseConfig = {
  // Config details redacted
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

Ideally what I am after is something similar to what Auth0 provides in there SDK example:

// router/index.js

//...some route
beforeEnter: authGuard()

Then authGuard would be in an external file. This file would hold the function that checks if a user is authenticated or not. Then I can add it to routes as needed.

Ari
  • 5,301
  • 8
  • 46
  • 120
  • 1
    You lay have a look at this [tutorial](https://savvyapps.com/blog/definitive-guide-building-web-app-vuejs-firebase), which shows one possible appproach. – Renaud Tarnec Sep 13 '20 at 13:07
  • @RenaudTarnec haha I literally just found that tutorial. Refactoring my setup to mimic this. Thanks. – Ari Sep 13 '20 at 13:14

2 Answers2

1

Use beforeEach router hook and check for route metadata. Here is a sample code from one of my apps

let router = new Router({
routes: [
    {path: '*', redirect: "/"},
    {
        path: "/",
        name: 'login',
        component: Login
    },
    {
        path: "/register",
        name: 'register',
        component: Register,
    },

    {
        path: "/home",
        name: "home",
        component: Home,
        meta: {
            requiresAuth: true
            }
      }


        ]

    },

],
mode: 'history'

})

router.beforeEach((to, from, next) => {
let currentUser = firebase.auth().currentUser;
console.log("firebasedata",currentUser);
if (to.matched.some(record => record.meta.requiresAuth)) {

    if (!currentUser) {
        next({
            path: '/login',
            query: {redirect: to.fullPath}
        })
    } else {
        if(to.matched.some(record => record.name==='login')){
            next({
                path: '/home',
                query: {redirect: to.fullPath}
            })

        }
        else {
            next();
        }

    }

} else {

    next();
}

})

export default router
Emmanuel Ogoma
  • 584
  • 5
  • 12
0

Import firebase Auth from your firebase config file, check if there is a current authenticated user in the cache. is there is then all routes can be accessed, if not use the "requiresAuth" variable to restrict access

import { auth } from '../plugins/firebase.js' //import auth from firebase config file

const routes = [
  {
    path: '/',
    component: () => import('@/layouts/default/Default.vue'),
    children: [
      {
        path: '',
        name: 'login',
        component: () => import('@/views/auth/Login.vue'),
      },
      {
        path: '/register',
        name: 'register',
        component: () => import('@/views/auth/Register.vue'),
      },
      {
        path: '/forgotPassword',
        name: 'forgotPassword',
        component: () => import('@/views/auth/ForgotPassword.vue'),
      },
      {
        path: '/app',
        name: 'app',
        component: () => import('@/views/app/Dashboard.vue'),
        meta: {
          requiresAuth: true // the route you want to protect
        },
      },
    ],
  },
]

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

//Protection code
router.beforeEach((to, from, next) => {
  const requiresAuth = to.matched.some(x => x.meta.requiresAuth)
  const user = auth.currentUser

  if (requiresAuth && !user) next('/')
  else if (requiresAuth && user) next()
  else next()
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
Rukkiecodes
  • 33
  • 1
  • 7