Sid Barrack
Sid Barrack

Reputation: 1231

how to implement role based authentification with nodejs?

basically I want a way for nodeJS to check if the user that has logged in through the login page is an admin or no if he is it should send him the admin page if he is not it should send him a different page.

i have one login page that is static for the moment, and i have two HTML pages each has a ton of jquery controllers so when i thought about rewriting all of this in view or react i realized it would take me an enormous amount of time to finish it i tried many solutions but either i only get the authentification part to work and not the authorization or the other way around.

i have a simple login form what i want to achieve is something like getting the form data and sending it with an ajax post and then the controller would first authenticate the user and then check what role he has if it's admin it should sendfile('index.html') if it's fm it should sendfile('req.html') i already wrote each page to be able to do a certain functionality and each of them is communicating with half a dozen different APIs so i won't need any new role and priviliges definitions not at least for now

Upvotes: 1

Views: 1052

Answers (2)

phemieny7
phemieny7

Reputation: 821

Well all i did was input a role to my user schema which runs from 1 to 4 and i set default to 4 which represent a normal user and 1-3 for different admin level, here is the code, it might help someone some day

User Schema:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Create Schema
const UserSchema = new Schema({
  email: {
    type: String,
    required: true
  },

  password: {
    type: String,
    required: true
  },
  role:{
    type: Number,
    default : 4,
  },

  date: {
    type: Date,
    default: Date.now
  },
});

module.exports = User = mongoose.model('users', UserSchema);

And here is the user signUp route

// @route   POST api/users/register
// @desc    Register user
// @access  Public
router.post('/register', (req, res) => {
  const { errors, isValid } = validateRegisterInput(req.body);

  // Check Validation 
  if (!isValid) {
    return res.status(400).json(errors);
  }

  User.find().sort({unitNo : -1}).then(user => {
        const newUser = new User(
      {
        email: req.body.email,
        password: req.body.password,
        });
     bcrypt.genSalt(10, (err, salt) => {
        bcrypt.hash(newUser.password, salt, (err, hash) => {
          if (err) throw err;
          newUser.password = hash;

            newUser 
             .save()
              .then(user => res.json(user))
              .catch(err => console.log(err));
        });
      });

  });
});

here is the user login

// @route   GET api/users/login
// @desc    Login User / Returning JWT Token
// @access  Public
router.post('/login', (req, res) => {
  const { errors, isValid } = validateLoginInput(req.body);

  // Check Validation
  if (!isValid) {
    return res.status(400).json(errors);
  }

  const email = req.body.email;
  const password = req.body.password;

  // Find user by email
  User.findOne({ email }).then(user => {
    // Check Password
    bcrypt.compare(password, user.password).then(isMatch => {
      if (isMatch) {
        // User Matched
        const payload = { id: user.id, name: user.name  }; // Create JWT Payload

        // Sign Token
        jwt.sign(
          payload,
          keys.secretOrKey,
          { expiresIn: 20000600 },
          (err, token) => {
            res.json({
              success: true,
              token: 'Bearer ' + token
            });
          }
        );
      } else {
        errors.password = 'Password incorrect';
        return res.status(400).json(errors);
      }
    });
  });
});

but for the admin that there roles ranges from 1-3 here is how there login looks like

// @route   Post api/admins/login
// @desc    Login User / Returning JWT Token
// @access  Public
router.post('/login', (req, res) => {
  const { errors, isValid } = validateLoginInput(req.body);

  // Check Validation
  if (!isValid) {
    return res.status(400).json(errors);
  }

  const email = req.body.email;
  const password = req.body.password;

  // Find user by email
  User.findOne({ email }).then(user => {
    // Check for Admin
    if (!user) {
      errors.email = 'User not found';
      return res.status(404).json(errors);
    }
    // Check to see if level meet admin role(Her is where i check if it is the admin or the user)
    if(user.role == 4){
      errors.role = 'You are not allowed to view this page'
      return res.status(404).json(errors);
    }

    // Check Password
    bcrypt.compare(password, user.password).then(isMatch => {
      if (isMatch) {
        // User Matched
        const payload = { id: user.id, name: user.name }; // Create JWT Payload

        // Sign Token
        jwt.sign(
          payload,
          keys.secretOrKey,
          { expiresIn: "7h" },
          (err, token) => {
            res.json({
              success: true,
              token: 'Bearer ' + token
            });
          }
        );
      } else {
        errors.password = 'Password incorrect';
        return res.status(400).json(errors);
      }
    });
  });
});

I hope this solve someone question someday...

Upvotes: 1

Sid Barrack
Sid Barrack

Reputation: 1231

ok since no one bothered to answer i wrote an article on medium for beginners interested in learning session based authentication and don't want to be overwhelmed by the thousands of frameworks and libraries out there. https://medium.com/@ahmedcheikhsidahmed/authentication-with-nodejs-expressjs-the-simple-way-945939878e16

Upvotes: 1

Related Questions