Simple Role-based Validation Techniques for AdonisJS

AdonisJS does not provide an access control list (ACL) feature out of the box. Here’s are a few simple ways to provide the right access to the right user when using AdonisJS.

Use ACL plugins

There are two plugins available for AdonisJS -

  1. Adonis ACL
  2. Advanced Adonis ACL

The usage is pretty simple. Follow the instructions in the package to install package as a provider.

Create a view based the role/permission data structure for ease-of-use. You could now create specific roles and permissions.

Roles are associated to user, then roles are then mapped to permissions, and permissions are associated to specific operations that a user can do.

Use simple validation within your code

Consider an example where user can update a ‘todo’ record only when she is the owner on the todo, or an admin.

In the controller, we introduce the following code -

// TodoController.js
async update({ params, request, auth }) {
    const user = await auth.getUser();
    const { id } = params;

    const todo = await Todo.findOrFail(id);

    if (user.role_cd != "admin" && user.id != todo.owner_id)
        throw new InvalidAccessException();

}

In the normal application flow -

  1. Route will check access to the route URL and pass the control flow to controller
  2. Controller will get user details from auth and id from params
  3. Find record
  4. If user.role is not admin and user’s id is not the same as owner_id, throw exception

Note that InvalidAccessException is a custom exception. See creating custom exceptions in AdonisJS to know more.

Final Word

ACL is the right way to implement role-based security in data-driven applications. However, implementing plgings may turn out to be an overkill if your requirements do not need granular permissions and roles.

Remember though - your future needs may change and that may bring in whole lot of complexities. I would advise to start with a the ACL plugin if you expect to have ‘> 5’ distinct roles and permission requirements.

comments powered by Disqus