Saturday, May 29, 2021

Role based authentication

 Add a new boolean field to users schema.

isAdmin.


And include that in jsonwebtoken payload. of models/user.js

const Joi = require("joi");
const mongoose = require("mongoose");
const jwt = require("jsonwebtoken");
const config = require("config");

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    minLength: 5,
    maxLength: 50,
    lowercase: true,
  },
  email: {
    type: String,
    required: true,
    minLength: 5,
    maxLength: 50,
    unique: true,
    lowercase: true,
  },
  password: {
    type: String,
    required: true,
    minLength: 5,
    maxLength: 255,
  },
  isAdmin: boolean
});

//can't use arrow function syntax as they don't have the this keyword.They use the calling function object reference.
//so class methods should not use arrow functions, they are only for normal functions.
userSchema.methods.generateAuthToken = function () {
  const token = jwt.sign({ _id: this._id,isAdmin: this.isAdmin }, config.get("jwtPrivateKey"));
  return token;
};

const User = mongoose.model("User"userSchema);

function validateUser(user) {
  const schema = Joi.object({
    name: Joi.string().min(5).max(50).required(),
    email: Joi.string().min(5).max(255).required().email(),
    password: Joi.string().min(5).max(255).required(),
  });
  return schema.validate(user);
}

exports.User = User;
exports.validate = validateUser;

Add a middleware to validate this middleware\admin.js

module.exports = function(req,res,next){
    if(!req.user.isAdmin)return res.status(403).send('Access denied');
}

//401 unauthorized
//403 forbidden


and add this middleware to existing routers along with the auth or other middleware in a list.


req.delete('/:id',[auth,admin],async(req,res)={

  

});



you can add role list to user schema and also operations list.

And control access using role is he having or the operations he have access to.

No comments:

Post a Comment