I created a node.js application (Bus-ticket-booking app). MongoDB is the database system I'm using. I haven't yet finished the front end. I'm doing API queries with Postman.
For authentication, I'm using JWT. Now I want to add roles and rules for users such as the app's administrator, supervisor, and normal user.
1 -> A user can have many roles assigned to them (admin, supervisor).
2 -> Permissions can be assigned to a role ( Create, Update, delete etc...).
As a result, a user can have one or more roles, and each role can have one or more permissions. A user can use APIs for which he has rights, such as creating data, deleting data, updating data, and so on.
Here is the user schema:
const userSchema = new mongoose.Schema({
firstname: {
type: String,
required: true,
},
lastname: {
type: String,
required: true,
},
email: {
type: String,
unique: true,
required: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error("Please provide the valid email address");
}
},
},
password: {
type: String,
required: true,
trim: true,
minLength: 8,
},
phone: {
type: Number,
required: true,
unique: true
},
tokens:[{
token: {
type: String,
required:true
}
}]
},{
timestamps:true
});
I'm new to it and have very little knowledge about it.
Is there anyone who can assist me?
If you just need a couple different roles, I suggest you go with Sajawal Hassan's concept of simply adding a boolean field to determine user's access level.
However, if you are planning to create where there are multitude of roles to be added, and do not want field to be added for each role:
1a. I suggest you create a list of roles within the user model file. Possibly a dictionary.
.../models/user.js
const ROLES = {
ADMIN: "ADMIN",
SUPERVISOR: "SUPERVISOR"
}
...
module.exports = mongoose.model('User', UserSchema);
module.exports.ROLES = ROLES;
1b. add a array field to Users models which will have the roles as permissions
.../user.js
const userSchema = new mongoose.Schema({
...,
permissions: [String],
...
});
.../auth.js
module.exports = function (options) {
...
// get user, validate token b4 here
user.permissions.forEach(permission => {
if (options.allowedGroup.indexOf(permission)){
// if authenticated
return next();
}
}
// could not authenticate at this point
return next(errorHandler) // throw a error or handle it way you want
}
3a. set up groups to determine which roles will have access to each router or a set of routers
.../routes/api_123.js
const mongoose = require('mongoose');
const User = mongoose.model('User');
const readGroup = [User.ROLES.SUPERVISOR, User.ROLES.ADMIN];
const writeGroup = [User.ROLES.ADMIN];
3b. pass the group you made as allowedGroup in param of middleware and set it up with a asyncHandler
...
const asyncHandler = require('express-async-handler');
...
router.get('/user/:id', auth({allowedGroup: readGroup}), asyncHandler(async(req, res, next) => {
... // your stuff here
res.status(200).json(data);
}))
router.post('/user/:id', auth({allowedGroup: writeGroup}), asyncHandler(async(req, res, next) => {
... // your stuff here
res.status(200).json(data);
}))