Skip to content

Commit f139c8b

Browse files
committed
first commit
0 parents  commit f139c8b

File tree

16 files changed

+513
-0
lines changed

16 files changed

+513
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
package-lock.json

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Node.js MongoDB – User Authentication & Authorization example with JWT & Mongoose
2+
3+
For more detail, please visit:
4+
> [Node.js + MongoDB: User Authentication & Authorization with JWT](https://bezkoder.com/node-js-mongodb-auth-jwt/)
5+
6+
Working with Front-end:
7+
> [Vue.js JWT Authentication with Vuex and Vue Router](https://bezkoder.com/jwt-vue-vuex-authentication/)
8+
9+
> [Angular 8 JWT Authentication with HttpInterceptor and Router](https://bezkoder.com/angular-jwt-authentication/)
10+
11+
## Project setup
12+
```
13+
npm install
14+
```
15+
16+
### Run
17+
```
18+
node server.js
19+
```

app/config/auth.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
secret: "bezkoder-secret-key"
3+
};

app/config/db.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
HOST: "localhost",
3+
PORT: 27017,
4+
DB: "bezkoder_db"
5+
};

app/controllers/auth.controller.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
const config = require("../config/auth.config");
2+
const db = require("../models");
3+
const User = db.user;
4+
const Role = db.role;
5+
6+
var jwt = require("jsonwebtoken");
7+
var bcrypt = require("bcryptjs");
8+
9+
exports.signup = (req, res) => {
10+
const user = new User({
11+
username: req.body.username,
12+
email: req.body.email,
13+
password: bcrypt.hashSync(req.body.password, 8)
14+
});
15+
16+
user.save((err, user) => {
17+
if (err) {
18+
res.status(500).send({ message: err });
19+
return;
20+
}
21+
22+
if (req.body.roles) {
23+
Role.find(
24+
{
25+
name: { $in: req.body.roles }
26+
},
27+
(err, roles) => {
28+
if (err) {
29+
res.status(500).send({ message: err });
30+
return;
31+
}
32+
33+
user.roles = roles.map(role => role._id);
34+
user.save(err => {
35+
if (err) {
36+
res.status(500).send({ message: err });
37+
return;
38+
}
39+
40+
res.send({ message: "User was registered successfully!" });
41+
});
42+
}
43+
);
44+
} else {
45+
Role.findOne({ name: "user" }, (err, role) => {
46+
if (err) {
47+
res.status(500).send({ message: err });
48+
return;
49+
}
50+
51+
user.roles = [role._id];
52+
user.save(err => {
53+
if (err) {
54+
res.status(500).send({ message: err });
55+
return;
56+
}
57+
58+
res.send({ message: "User was registered successfully!" });
59+
});
60+
});
61+
}
62+
});
63+
};
64+
65+
exports.signin = (req, res) => {
66+
User.findOne({
67+
username: req.body.username
68+
})
69+
.populate("roles", "-__v")
70+
.exec((err, user) => {
71+
if (err) {
72+
res.status(500).send({ message: err });
73+
return;
74+
}
75+
76+
if (!user) {
77+
return res.status(404).send({ message: "User Not found." });
78+
}
79+
80+
var passwordIsValid = bcrypt.compareSync(
81+
req.body.password,
82+
user.password
83+
);
84+
85+
if (!passwordIsValid) {
86+
return res.status(401).send({
87+
accessToken: null,
88+
message: "Invalid Password!"
89+
});
90+
}
91+
92+
var token = jwt.sign({ id: user.id }, config.secret, {
93+
expiresIn: 86400 // 24 hours
94+
});
95+
96+
var authorities = [];
97+
98+
for (let i = 0; i < user.roles.length; i++) {
99+
authorities.push("ROLE_" + user.roles[i].name.toUpperCase());
100+
}
101+
res.status(200).send({
102+
id: user._id,
103+
username: user.username,
104+
email: user.email,
105+
roles: authorities,
106+
accessToken: token
107+
});
108+
});
109+
};

app/controllers/user.controller.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
exports.allAccess = (req, res) => {
2+
res.status(200).send("Public Content.");
3+
};
4+
5+
exports.userBoard = (req, res) => {
6+
res.status(200).send("User Content.");
7+
};
8+
9+
exports.adminBoard = (req, res) => {
10+
res.status(200).send("Admin Content.");
11+
};
12+
13+
exports.moderatorBoard = (req, res) => {
14+
res.status(200).send("Moderator Content.");
15+
};

app/middlewares/authJwt.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const jwt = require("jsonwebtoken");
2+
const config = require("../config/auth.config.js");
3+
const db = require("../models");
4+
const User = db.user;
5+
const Role = db.role;
6+
7+
verifyToken = (req, res, next) => {
8+
let token = req.headers["x-access-token"];
9+
10+
if (!token) {
11+
return res.status(403).send({ message: "No token provided!" });
12+
}
13+
14+
jwt.verify(token, config.secret, (err, decoded) => {
15+
if (err) {
16+
return res.status(401).send({ message: "Unauthorized!" });
17+
}
18+
req.userId = decoded.id;
19+
next();
20+
});
21+
};
22+
23+
isAdmin = (req, res, next) => {
24+
User.findById(req.userId).exec((err, user) => {
25+
if (err) {
26+
res.status(500).send({ message: err });
27+
return;
28+
}
29+
30+
Role.find(
31+
{
32+
_id: { $in: user.roles }
33+
},
34+
(err, roles) => {
35+
if (err) {
36+
res.status(500).send({ message: err });
37+
return;
38+
}
39+
40+
for (let i = 0; i < roles.length; i++) {
41+
if (roles[i].name === "admin") {
42+
next();
43+
return;
44+
}
45+
}
46+
47+
res.status(403).send({ message: "Require Admin Role!" });
48+
return;
49+
}
50+
);
51+
});
52+
};
53+
54+
isModerator = (req, res, next) => {
55+
User.findById(req.userId).exec((err, user) => {
56+
if (err) {
57+
res.status(500).send({ message: err });
58+
return;
59+
}
60+
61+
Role.find(
62+
{
63+
_id: { $in: user.roles }
64+
},
65+
(err, roles) => {
66+
if (err) {
67+
res.status(500).send({ message: err });
68+
return;
69+
}
70+
71+
for (let i = 0; i < roles.length; i++) {
72+
if (roles[i].name === "moderator") {
73+
next();
74+
return;
75+
}
76+
}
77+
78+
res.status(403).send({ message: "Require Moderator Role!" });
79+
return;
80+
}
81+
);
82+
});
83+
};
84+
85+
const authJwt = {
86+
verifyToken,
87+
isAdmin,
88+
isModerator
89+
};
90+
module.exports = authJwt;

app/middlewares/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const authJwt = require("./authJwt");
2+
const verifySignUp = require("./verifySignUp");
3+
4+
module.exports = {
5+
authJwt,
6+
verifySignUp
7+
};

app/middlewares/verifySignUp.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const db = require("../models");
2+
const ROLES = db.ROLES;
3+
const User = db.user;
4+
5+
checkDuplicateUsernameOrEmail = (req, res, next) => {
6+
// Username
7+
User.findOne({
8+
username: req.body.username
9+
}).exec((err, user) => {
10+
if (err) {
11+
res.status(500).send({ message: err });
12+
return;
13+
}
14+
15+
if (user) {
16+
res.status(400).send({ message: "Failed! Username is already in use!" });
17+
return;
18+
}
19+
20+
// Email
21+
User.findOne({
22+
email: req.body.email
23+
}).exec((err, user) => {
24+
if (err) {
25+
res.status(500).send({ message: err });
26+
return;
27+
}
28+
29+
if (user) {
30+
res.status(400).send({ message: "Failed! Email is already in use!" });
31+
return;
32+
}
33+
34+
next();
35+
});
36+
});
37+
};
38+
39+
checkRolesExisted = (req, res, next) => {
40+
if (req.body.roles) {
41+
for (let i = 0; i < req.body.roles.length; i++) {
42+
if (!ROLES.includes(req.body.roles[i])) {
43+
res.status(400).send({
44+
message: `Failed! Role ${req.body.roles[i]} does not exist!`
45+
});
46+
return;
47+
}
48+
}
49+
}
50+
51+
next();
52+
};
53+
54+
const verifySignUp = {
55+
checkDuplicateUsernameOrEmail,
56+
checkRolesExisted
57+
};
58+
59+
module.exports = verifySignUp;

app/models/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const mongoose = require('mongoose');
2+
mongoose.Promise = global.Promise;
3+
4+
const db = {};
5+
6+
db.mongoose = mongoose;
7+
8+
db.user = require("./user.model");
9+
db.role = require("./role.model");
10+
11+
db.ROLES = ["user", "admin", "moderator"];
12+
13+
module.exports = db;

0 commit comments

Comments
 (0)