Skip to content

Commit

Permalink
role based login authetication with node js api
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamyashah2807 committed Mar 8, 2022
1 parent 7c3650c commit fa585df
Show file tree
Hide file tree
Showing 16 changed files with 1,967 additions and 0 deletions.
2 changes: 2 additions & 0 deletions backend/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

web:node server.js
3 changes: 3 additions & 0 deletions backend/app/config/auth.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
secret: "mean_theme"
};
109 changes: 109 additions & 0 deletions backend/app/controllers/auth.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
const config = require("../config/auth.config");
const db = require("../models");
const User = db.user;
const Role = db.role;

var jwt = require("jsonwebtoken");
var bcrypt = require("bcryptjs");

exports.signup = (req, res) => {
const user = new User({
username: req.body.username,
email: req.body.email,
password: bcrypt.hashSync(req.body.password, 8)
});

user.save((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}

if (req.body.roles) {
Role.find(
{
name: { $in: req.body.roles }
},
(err, roles) => {
if (err) {
res.status(500).send({ message: err });
return;
}

user.roles = roles.map(role => role._id);
user.save(err => {
if (err) {
res.status(500).send({ message: err });
return;
}

res.send({ message: "User was registered successfully!" });
});
}
);
} else {
Role.findOne({ name: "user" }, (err, role) => {
if (err) {
res.status(500).send({ message: err });
return;
}

user.roles = [role._id];
user.save(err => {
if (err) {
res.status(500).send({ message: err });
return;
}

res.send({ message: "User was registered successfully!" });
});
});
}
});
};

exports.signin = (req, res) => {
User.findOne({
username: req.body.username
})
.populate("roles", "-__v")
.exec((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}

if (!user) {
return res.status(404).send({ message: "User Not found." });
}

var passwordIsValid = bcrypt.compareSync(
req.body.password,
user.password
);

if (!passwordIsValid) {
return res.status(401).send({
accessToken: null,
message: "Invalid Password!"
});
}

var token = jwt.sign({ id: user.id }, config.secret, {
expiresIn: 86400 // 24 hours
});

var authorities = [];

for (let i = 0; i < user.roles.length; i++) {
authorities.push("ROLE_" + user.roles[i].name.toUpperCase());
}
res.status(200).send({
id: user._id,
username: user.username,
email: user.email,
roles: authorities,
accessToken: token
});
});
};
12 changes: 12 additions & 0 deletions backend/app/controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
exports.allAccess = (req, res) => {
res.status(200).send("Public Content.");
};

exports.userBoard = (req, res) => {
res.status(200).send("User Content.");
};

exports.adminBoard = (req, res) => {
res.status(200).send("Admin Content.");
};

58 changes: 58 additions & 0 deletions backend/app/middlewares/authJwt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const jwt = require("jsonwebtoken");
const config = require("../config/auth.config.js");
const db = require("../models");
const User = db.user;
const Role = db.role;

verifyToken = (req, res, next) => {
let token = req.headers["x-access-token"];

if (!token) {
return res.status(403).send({ message: "No token provided!" });
}

jwt.verify(token, config.secret, (err, decoded) => {
if (err) {
return res.status(401).send({ message: "Unauthorized!" });
}
req.userId = decoded.id;
next();
});
};

isAdmin = (req, res, next) => {
User.findById(req.userId).exec((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}

Role.find(
{
_id: { $in: user.roles }
},
(err, roles) => {
if (err) {
res.status(500).send({ message: err });
return;
}

for (let i = 0; i < roles.length; i++) {
if (roles[i].name === "admin") {
next();
return;
}
}

res.status(403).send({ message: "Require Admin Role!" });
return;
}
);
});
};

const authJwt = {
verifyToken,
isAdmin,
};
module.exports = authJwt;
7 changes: 7 additions & 0 deletions backend/app/middlewares/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const authJwt = require("./authJwt");
const verifySignUp = require("./verifySignup");

module.exports = {
authJwt,
verifySignUp
};
59 changes: 59 additions & 0 deletions backend/app/middlewares/verifySignup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const db = require("../models");
const ROLES = db.ROLES;
const User = db.user;

checkDuplicateUsernameOrEmail = (req, res, next) => {
// Username
User.findOne({
username: req.body.username
}).exec((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}

if (user) {
res.status(400).send({ message: "Failed! Username is already in use!" });
return;
}

// Email
User.findOne({
email: req.body.email
}).exec((err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}

if (user) {
res.status(400).send({ message: "Failed! Email is already in use!" });
return;
}

next();
});
});
};

checkRolesExisted = (req, res, next) => {
if (req.body.roles) {
for (let i = 0; i < req.body.roles.length; i++) {
if (!ROLES.includes(req.body.roles[i])) {
res.status(400).send({
message: `Failed! Role ${req.body.roles[i]} does not exist!`
});
return;
}
}
}

next();
};

const verifySignUp = {
checkDuplicateUsernameOrEmail,
checkRolesExisted
};

module.exports = verifySignUp;
13 changes: 13 additions & 0 deletions backend/app/models/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;

const db = {};

db.mongoose = mongoose;

db.user = require("./user.model");
db.role = require("./role.model");

db.ROLES = ["user", "admin"];

module.exports = db;
10 changes: 10 additions & 0 deletions backend/app/models/role.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const mongoose = require("mongoose");

const Role = mongoose.model(
"Role",
new mongoose.Schema({
name: String
})
);

module.exports = Role;
18 changes: 18 additions & 0 deletions backend/app/models/user.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const mongoose = require("mongoose");

const User = mongoose.model(
"User",
new mongoose.Schema({
username: String,
email: String,
password: String,
roles: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Role"
}
]
})
);

module.exports = User;
23 changes: 23 additions & 0 deletions backend/app/routes/auth.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { verifySignUp } = require("../middlewares");
const controller = require("../controllers/auth.controller");

module.exports = function (app) {
app.use(function (req, res, next) {
res.header(
"Access-Control-Allow-Headers",
"x-access-token, Origin, Content-Type, Accept"
);
next();
});

app.post(
"/api/auth/signup",
[
verifySignUp.checkDuplicateUsernameOrEmail,
verifySignUp.checkRolesExisted
],
controller.signup
);

app.post("/api/auth/signin", controller.signin);
};
22 changes: 22 additions & 0 deletions backend/app/routes/user.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const { authJwt } = require("../middlewares");
const controller = require("../controllers/user.controller");

module.exports = function (app) {
app.use(function (req, res, next) {
res.header(
"Access-Control-Allow-Headers",
"x-access-token, Origin, Content-Type, Accept"
);
next();
});

app.get("/api/test/all", controller.allAccess);

app.get("/api/test/user", [authJwt.verifyToken], controller.userBoard);

app.get(
"/api/test/admin",
[authJwt.verifyToken, authJwt.isAdmin],
controller.adminBoard
);
};
1 change: 1 addition & 0 deletions backend/config.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DATABASE=mongodb+srv://Kamyashah2807:shahkamya@cluster0.cadgu.mongodb.net/mean_project?retryWrites=true&w=majority
Loading

0 comments on commit fa585df

Please sign in to comment.