Nuxt Guard/Protect User and Admin Pages Using Middleware and Firebase Authentication

Firebase Authentication

Setup Firebase Authentication With Nuxt.js.

I will use Custom Claims to setup admin flags.

  • Authenticated user can access /console
  • Only admin can access /admin

Edit store/index.js (Vuex Store) to add support for custom claims

export const state = () => ({  user: null})export const mutations = {  ON_AUTH_STATE_CHANGED_MUTATION: async (state, { authUser, claims }) => {    if (authUser) {      state.user = {        uid: authUser.uid,        // email: authUser.email,        displayName: authUser.displayName,        admin: claims.admin      }      /*      const idTokenResult = await authUser.getIdTokenResult()      if (!!idTokenResult.claims.active) {        state.user.active = true      }      else {        state.user.active = false      }       */    }    else {      state.user = null    }  }}

How to you assign admin provilege to a specific user? Depending on your use case, you could use a cloud functions or cli.

Using Node.js

await admin.auth().setCustomUserClaims(uid, {admin: true})

NOTE: Refer Firebase Admin Setup

Using Python

auth.set_custom_user_claims(uid, {'admin': True})

Guard Pages

We use nuxt middleware to protect pages like /console (authenticated user only) and /admin (admin only)

Edit nuxt.config.js

export default {  router: {    middleware: 'router-auth'  },}

Edit middleware/router-auth.js

export default function({ store, redirect, error, route }) {  // console.log('user', store.state.user)  if (!isAuthenticated(store.state.user) && requireAuthentication(route))    redirect('/') // /login  else if (!isAdmin(store.state.user) && requireAdmin(route))    // redirect('/error_admin_only')    // redirect('/error', { code: 'require_admin' })    error({      statusCode: 401,      message: 'Only Admin is allowed to access this page'    })    }function isAuthenticated(user) {  return user}function requireAuthentication(route) {  // return !['/', '/about', '/login'].includes(route.path) // || !route.path.startswith('/error_')  return ['/console'].includes(route.path)}function isAdmin(user) {  return user && user.admin}function requireAdmin(route) {  return ['/admin'].includes(route.path)}

Edit pages/console.vue

<template>  <h1>Console</h1></template>

Edit pages/admin.vue

<template>  <h1>Admin</h1></template>

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.