Let's say I have 3 models: Admin, User, Product (I'm using model classes)
Only an admin can ADD, UPDATE, DELETE a product and users can only GET products, so I have registered an ACL middleware for corresponding routes.
Now in my ACL middleware, I want to authorize users, and if they are ADMIN, I will call next()
method, otherwise, I'm going to reject the request with a 401
.
I found it easy to do the check using JavaScript's instanceof
operator:
const user = await auth.authenticate()
if (user instanceof Admin) {
await next()
} else {
throw UnAuthorizedUserException
}
await auth.authenticate()
returns the current user sending the request, be it a user or an admin
However, I'm not sure if this is the safest way to distinguish b/w admins and users.
Now my question is, am I doing it right? Which approach is better than what I'm doing?
Note (if it helps): I'm using Adonis.js v5, TypeScript and Lucid models
Yes you can do this. You will need to be careful about inheritance patterns if you use this approach. You may want to consider adding a role property to the user object and using that for the check.
example using a role prop.
if (user.role === 'ADMIN') {
...
}
example of instanceof backfiring on you
class User {}
class Admin extends User {}
const user = new User;
const admin = new Admin;
console.log(user instanceof User); // true
console.log(user instanceof Admin); // false
console.log(admin instanceof User); // true **watch out for this**
console.log(admin instanceof Admin); // true