This page looks best with JavaScript enabled

Role-based Access to Routes in AdonisJS

 ·   ·  ☕ 2 min read

AdonisJS provides a standard way to define a middleware and enable access to routes based on defined validation rules. This middleware is leveraged to allow role-based access to routes.

Your start | routes.js file will have something akin to below -

1
2
3
4
5
const Route = use("Route");

Route.get("/", () => {
  return { greeting: "Hello world!" };
});

First, we will group routes for the different roles and introduce the middleware.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// start | Routes.js
Route.group(() => {
  Route.post("/user-register", "UserController.register");
  Route.post("/user-login", "UserController.login");
});

Route.group(() => {
  Route.get("/todo", "TodoController.index");
  Route.post("/todo", "TodoController.create");
}).middleware("auth");

Route.group(() => {
  Route.delete("/todo", "TodoController.delete");
}).middleware(["auth", "admin"]);
  • register and login methods are available to unauthenticated and authenticated users
  • To do create and index are available only to authenticated users. auth is provided by AdonisJS
  • Deleting to do is allowed only for admin

Now, we write the actual middleware for admin.

Create a admin.js file in app| Middleware folder under root. Introduce the following code -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
"use strict";

const InvalidAccessException = use("App/Exceptions/InvalidAccessException");

class Admin {
  async handle({ request, auth }, next) {
    const user = await auth.getUser();

    if (!user.role_cd || user.role_cd != "admin")
      throw new InvalidAccessException();

    await next();
  }
}

module.exports = Admin;

What happens when a user tries to access the delete route -

  • Adonis executes the auth and admin middleware
  • auth passes ok if user is authenticated
  • admin checks if the user.role_cd, a custom field, has the value ‘admin’. If this does not check out, an exception is thrown
  • InvalidAccessException is a custom exception that returns a 404 with a custom message (see [custom exceptions in Adonis)(/custom-exceptions-in-adonisjs/)

In a previous post we had a short discussion on implementing access rules in Adonis based on roles. Should you implement that vs. implementing the above in routes?

Well - it depends.

  • If the entire route is cordoned off to roles, you have a cleaner approach using role-based validation at the route level.
  • For everything else, let your controller take the lead for role-based authentication

In the real world, you would want to implement a separate service for role-based auth. This service can be called by your route middleware, or your controllers depending on your use case.

Stay in touch!
Share on

Prashanth Krishnamurthy
WRITTEN BY
Prashanth Krishnamurthy
Technologist | Creator of Things