Protecting Routes with Middleware in Vue Applications

When building Single Page Applications (SPAs), it’s essential to protect certain routes from unauthorized access. In this article, we’ll explore how to implement a middleware pipeline in a Vue application using Vue-Router.

What is a Middleware Pipeline?

A middleware pipeline is a stack of functions that run in parallel, allowing you to chain multiple middlewares together. This approach enables you to protect routes with multiple conditions, such as authentication and subscription status.

Getting Started

To demonstrate the concept, let’s create a simple Vue application with three components: Login, Dashboard, and Movies. We’ll use Vue-Router to manage client-side routing and Vuex for state management.

Creating Components

Create the following files in the src/components directory:

  • Login.vue
  • Dashboard.vue
  • Movies.vue

Creating the Store

Create a store.js file in the src directory to manage the application state:
“`javascript
import Vuex from ‘vuex’

const store = new Vuex.Store({
state: {
user: {
loggedIn: false,
isSubscribed: false
}
},
getters: {
getUser(state) {
return state.user
}
}
})

export default store
“`
Defining Routes

Define the routes and associate them with the corresponding middlewares:
“`javascript
import Vue from ‘vue’
import VueRouter from ‘vue-router’
import store from ‘./store’

Vue.use(VueRouter)

const routes = [
{
path: ‘/login’,
component: Login,
meta: {
middleware: [‘guest’]
}
},
{
path: ‘/dashboard’,
component: Dashboard,
meta: {
middleware: [‘auth’]
}
},
{
path: ‘/dashboard/movies’,
component: Movies,
meta: {
middleware: [‘auth’, ‘isSubscribed’]
}
}
]

const router = new VueRouter({
routes
})
“`
Creating Middlewares

Create the following middleware files in the src/router/middleware directory:

  • guest.js
  • auth.js
  • isSubscribed.js

Implementing Middlewares

Implement the middleware logic in each file:
“`javascript
// guest.js
import store from ‘../../store’

export default async (context) => {
if (store.getters.getUser.loggedIn) {
context.redirect(‘/dashboard’)
}
}

// auth.js
import store from ‘../../store’

export default async (context) => {
if (!store.getters.getUser.loggedIn) {
context.redirect(‘/login’)
}
}

// isSubscribed.js
import store from ‘../../store’

export default async (context) => {
if (!store.getters.getUser.isSubscribed) {
context.redirect(‘/dashboard’)
}
}
“`
Running Middlewares

Use the beforeEach hook to run the middlewares:
javascript
router.beforeEach((to, from, next) => {
const middleware = to.meta.middleware
if (middleware) {
middleware.forEach((middleware) => {
middleware({ to, from, next })
})
} else {
next()
}
})

Creating a Middleware Pipeline

Create a middlewarePipeline.js file to manage the middleware pipeline:
“`javascript
import store from ‘../../store’

export default async (context, middleware, index) => {
const nextMiddleware = middleware[index]
if (nextMiddleware) {
await nextMiddleware(context)
await middlewarePipeline(context, middleware, index + 1)
}
}
“`
Bringing it all Together

Update the beforeEach hook to use the middleware pipeline:
javascript
router.beforeEach((to, from, next) => {
const middleware = to.meta.middleware
if (middleware) {
middlewarePipeline({ to, from, next }, middleware, 0)
} else {
next()
}
})

With this implementation, you can now protect your routes with multiple middlewares, ensuring that only authorized users can access specific pages.

Leave a Reply

Your email address will not be published. Required fields are marked *