Nuxt Guard/Protect User and Admin Pages Using Middleware and Firebase Authentication
November 18, 2020Firebase 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>
- algolia
- analytics
- android
- android-ktx
- android-permission
- android-studio
- apps-script
- bash
- bootstrap
- bootstrapvue
- chartjs
- chrome
- cloud-functions
- coding-interview
- coroutines
- crashlytics
- css
- dagger2
- datastore
- datetime
- docker
- eslint
- firebase
- firebase-auth
- firebase-hosting
- firestore
- firestore-security-rules
- flask
- fontawesome
- fresco
- git
- github
- glide
- google-app-engine
- google-cloud-storage
- google-colab
- google-drive
- google-maps
- google-places
- google-play
- google-sheets
- gradle
- html
- hugo
- inkscape
- java
- java-time
- javascript
- jetson-nano
- kotlin
- layout
- lets-encrypt
- lifecycle
- linux
- logging
- lubuntu
- markdown
- mate
- material-design
- matplotlib
- md5
- mongodb
- moshi
- mplfinance
- mysql
- navigation
- nginx
- nodejs
- npm
- nuxtjs
- nvm
- pandas
- payment
- pip
- pwa
- pyenv
- python
- recylerview
- regex
- room
- rxjava
- scoped-storage
- selenium
- social-media
- ssh
- ssl
- static-site-generator
- static-website-hosting
- sublime-text
- ubuntu
- unit-test
- uwsgi
- viewmodel
- viewpager2
- virtualbox
- vue-chartjs
- vue-cli
- vue-router
- vuejs
- vuelidate
- vuepress
- web-development
- web-hosting
- webpack
- windows
- workmanager
- wsl
- yarn