├── .gitignore ├── config ├── database.js └── passport.js ├── package.json ├── models ├── User.js └── Admin.js ├── app.js └── routes ├── users.js └── admin.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /config/database.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | database: 'mongodb://localhost:27017/authentication_app', 3 | secret: 'yoursecret' 4 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "Simple role based authentication system", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "Simple", 11 | "role", 12 | "based", 13 | "authentication", 14 | "system" 15 | ], 16 | "author": "Nandy Mandy", 17 | "license": "MIT", 18 | "dependencies": { 19 | "bcryptjs": "^2.4.3", 20 | "body-parser": "^1.18.3", 21 | "cors": "^2.8.5", 22 | "express": "^4.16.4", 23 | "jsonwebtoken": "^8.5.0", 24 | "mongoose": "^5.4.16", 25 | "mongoose-unique-validator": "^2.0.2", 26 | "passport": "^0.4.0", 27 | "passport-jwt": "^4.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /config/passport.js: -------------------------------------------------------------------------------- 1 | const JwtStrategy = require('passport-jwt').Strategy; 2 | const ExtractJwt = require('passport-jwt').ExtractJwt; 3 | const User = require('../models/User'); 4 | const Admin = require('../models/Admin'); 5 | const config = require('../config/database'); 6 | 7 | // To authtenticate the User by JWT Startegy 8 | module.exports = (userType, passport) => { 9 | let opts = {}; 10 | opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt'); 11 | opts.secretOrKey = config.secret; 12 | passport.use(new JwtStrategy(opts, (jwt_payload, done) => { 13 | if (userType == 'admin') { 14 | Admin.getAdminById(jwt_payload.data._id, (err, user) => { 15 | if (err) return done(err, false); 16 | if (user) return done(null, user); 17 | return done(null, false); 18 | }); 19 | } 20 | if (userType == 'users') { 21 | User.getUserById(jwt_payload.data._id, (err, user) => { 22 | if (err) return done(err, false); 23 | if (user) return done(null, user); 24 | return done(null, false); 25 | }); 26 | } 27 | })); 28 | } -------------------------------------------------------------------------------- /models/User.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const bcrypt = require('bcryptjs'); 3 | const uniqueValidator = require('mongoose-unique-validator'); 4 | 5 | // User Schema 6 | const UserSchema = mongoose.Schema({ 7 | name: { 8 | type: String, 9 | required: true 10 | }, 11 | email: { 12 | type: String, 13 | unique: true, 14 | index: true, 15 | required: true 16 | }, 17 | username: { 18 | type: String, 19 | unique: true, 20 | required: true 21 | }, 22 | password: { 23 | type: String, 24 | required: true 25 | }, 26 | contact: { 27 | type: String, 28 | required: true 29 | } 30 | }); 31 | 32 | UserSchema.plugin(uniqueValidator); 33 | 34 | const User = module.exports = mongoose.model('User', UserSchema); 35 | 36 | // Find the user by ID 37 | module.exports.getUserById = function (id, callback) { 38 | User.findById(id, callback); 39 | } 40 | 41 | // Find the user by Its username 42 | module.exports.getUserByUsername = function (username, callback) { 43 | const query = { 44 | username: username 45 | } 46 | User.findOne(query, callback); 47 | } 48 | 49 | // to Register the user 50 | module.exports.addUser = function (newUser, callback) { 51 | bcrypt.genSalt(10, (err, salt) => { 52 | bcrypt.hash(newUser.password, salt, (err, hash) => { 53 | if (err) throw err; 54 | newUser.password = hash; 55 | newUser.save(callback); 56 | }); 57 | }); 58 | } 59 | 60 | // Compare Password 61 | module.exports.comparePassword = function (password, hash, callback) { 62 | bcrypt.compare(password, hash, (err, isMatch) => { 63 | if (err) throw err; 64 | callback(null, isMatch); 65 | }); 66 | } -------------------------------------------------------------------------------- /models/Admin.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const bcrypt = require('bcryptjs'); 3 | const uniqueValidator = require('mongoose-unique-validator'); 4 | 5 | // Admin Schema 6 | const AdminSchema = mongoose.Schema({ 7 | name: { 8 | type: String, 9 | required: true 10 | }, 11 | email: { 12 | type: String, 13 | unique: true, 14 | index: true, 15 | required: true 16 | }, 17 | username: { 18 | type: String, 19 | unique: true, 20 | required: true 21 | }, 22 | password: { 23 | type: String, 24 | required: true 25 | }, 26 | contact: { 27 | type: String, 28 | required: true 29 | }, 30 | job_profile: { 31 | type: String, 32 | required: true 33 | } 34 | }); 35 | 36 | AdminSchema.plugin(uniqueValidator); 37 | 38 | const Admin = module.exports = mongoose.model('Admin', AdminSchema); 39 | 40 | // Find the Admin by ID 41 | module.exports.getAdminById = function (id, callback) { 42 | Admin.findById(id, callback); 43 | } 44 | 45 | // Find the Admin by Its username 46 | module.exports.getAdminByUsername = function (username, callback) { 47 | const query = { 48 | username: username 49 | } 50 | Admin.findOne(query, callback); 51 | } 52 | 53 | // to Register the Admin 54 | module.exports.addAdmin = function (newAdmin, callback) { 55 | bcrypt.genSalt(10, (err, salt) => { 56 | bcrypt.hash(newAdmin.password, salt, (err, hash) => { 57 | if (err) throw err; 58 | newAdmin.password = hash; 59 | newAdmin.save(callback); 60 | }); 61 | }); 62 | } 63 | 64 | // Compare Password 65 | module.exports.comparePassword = function (password, hash, callback) { 66 | bcrypt.compare(password, hash, (err, isMatch) => { 67 | if (err) throw err; 68 | callback(null, isMatch); 69 | }); 70 | } -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const mongoose = require('mongoose'); 3 | const bodyParser = require('body-parser'); 4 | const cors = require('cors'); 5 | const passport = require('passport'); 6 | const path = require('path'); 7 | 8 | // Bring in the database object 9 | const config = require('./config/database'); 10 | 11 | // Mongodb Config 12 | mongoose.set('useCreateIndex', true); 13 | 14 | // Connect with the database 15 | mongoose.connect(config.database, { 16 | useNewUrlParser: true 17 | }) 18 | .then(() => { 19 | console.log('Databse connected successfully ' + config.database); 20 | }).catch(err => { 21 | console.log(err); 22 | }); 23 | 24 | // Initialize the app 25 | const app = express(); 26 | 27 | // Defining the PORT 28 | const PORT = process.env.PORT || 5000; 29 | 30 | // Defining the Middlewares 31 | app.use(cors()); 32 | 33 | // Set the static folder 34 | app.use(express.static(path.join(__dirname, 'public'))); 35 | 36 | // BodyParser Middleware 37 | app.use(bodyParser.json()); 38 | // Passport Middleware 39 | app.use(passport.initialize()); 40 | app.use(passport.session()); 41 | 42 | 43 | app.get('/', (req, res) => { 44 | return res.json({ 45 | message: "This is node.js role based authentication system" 46 | }); 47 | }); 48 | 49 | // Create a custom middleware function 50 | const checkUserType = function (req, res, next) { 51 | const userType = req.originalUrl.split('/')[2]; 52 | // Bring in the passport authentication starategy 53 | require('./config/passport')(userType, passport); 54 | next(); 55 | }; 56 | 57 | app.use(checkUserType); 58 | 59 | 60 | 61 | 62 | // Bring in the user routes 63 | const users = require('./routes/users'); 64 | app.use('/api/users', users); 65 | 66 | const admin = require('./routes/admin'); 67 | app.use('/api/admin', admin); 68 | 69 | 70 | app.listen(PORT, () => { 71 | console.log(`Server started on port ${PORT}`); 72 | }); -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const passport = require('passport'); 4 | const jwt = require('jsonwebtoken'); 5 | const User = require('../models/User'); 6 | const config = require('../config/database'); 7 | 8 | 9 | router.post('/register', (req, res) => { 10 | let newUser = new User({ 11 | name: req.body.name, 12 | username: req.body.username, 13 | email: req.body.email, 14 | contact: req.body.contact, 15 | password: req.body.password 16 | }); 17 | User.addUser(newUser, (err, user) => { 18 | if (err) { 19 | let message = ""; 20 | if (err.errors.username) message = "Username is already taken. "; 21 | if (err.errors.email) message += "Email already exists."; 22 | return res.json({ 23 | success: false, 24 | message 25 | }); 26 | } else { 27 | return res.json({ 28 | success: true, 29 | message: "User registration is successful." 30 | }); 31 | } 32 | }); 33 | }); 34 | 35 | router.post('/login', (req, res) => { 36 | const username = req.body.username; 37 | const password = req.body.password; 38 | 39 | User.getUserByUsername(username, (err, user) => { 40 | if (err) throw err; 41 | if (!user) { 42 | return res.json({ 43 | success: false, 44 | message: "User not found." 45 | }); 46 | } 47 | 48 | User.comparePassword(password, user.password, (err, isMatch) => { 49 | if (err) throw err; 50 | if (isMatch) { 51 | const token = jwt.sign({ 52 | type: "user", 53 | data: { 54 | _id: user._id, 55 | username: user.username, 56 | name: user.name, 57 | email: user.email, 58 | contact: user.contact 59 | } 60 | }, config.secret, { 61 | expiresIn: 604800 // for 1 week time in milliseconds 62 | }); 63 | return res.json({ 64 | success: true, 65 | token: "JWT " + token 66 | }); 67 | } else { 68 | return res.json({ 69 | success: true, 70 | message: "Wrong Password." 71 | }); 72 | } 73 | }); 74 | }); 75 | }); 76 | 77 | /** 78 | * Get Authenticated user profile 79 | */ 80 | 81 | router.get('/profile', passport.authenticate('jwt', { 82 | session: false 83 | }), (req, res) => { 84 | // console.log(req.user); 85 | return res.json( 86 | req.user 87 | ); 88 | }); 89 | 90 | module.exports = router; -------------------------------------------------------------------------------- /routes/admin.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const passport = require('passport'); 4 | const jwt = require('jsonwebtoken'); 5 | const Admin = require('../models/Admin'); 6 | const config = require('../config/database'); 7 | 8 | 9 | router.post('/register', (req, res) => { 10 | let newAdmin = new Admin({ 11 | name: req.body.name, 12 | username: req.body.username, 13 | email: req.body.email, 14 | contact: req.body.contact, 15 | password: req.body.password, 16 | job_profile: req.body.job_profile 17 | }); 18 | Admin.addAdmin(newAdmin, (err, user) => { 19 | if (err) { 20 | let message = ""; 21 | if (err.errors.username) message = "Username is already taken. "; 22 | if (err.errors.email) message += "Email already exists."; 23 | return res.json({ 24 | success: false, 25 | message 26 | }); 27 | } else { 28 | return res.json({ 29 | success: true, 30 | message: "Admin registration is successful." 31 | }); 32 | } 33 | }); 34 | }); 35 | 36 | router.post('/login', (req, res) => { 37 | const username = req.body.username; 38 | const password = req.body.password; 39 | 40 | Admin.getAdminByUsername(username, (err, admin) => { 41 | if (err) throw err; 42 | if (!admin) { 43 | return res.json({ 44 | success: false, 45 | message: "Admin not found." 46 | }); 47 | } 48 | 49 | Admin.comparePassword(password, admin.password, (err, isMatch) => { 50 | if (err) throw err; 51 | if (isMatch) { 52 | const token = jwt.sign({ 53 | type: "admin", 54 | data: { 55 | _id: admin._id, 56 | username: admin.username, 57 | name: admin.name, 58 | email: admin.email, 59 | contact: admin.contact, 60 | job_profile: admin.job_profile 61 | } 62 | }, config.secret, { 63 | expiresIn: 604800 // for 1 week time in milliseconds 64 | }); 65 | return res.json({ 66 | success: true, 67 | token: "JWT " + token 68 | }); 69 | } else { 70 | return res.json({ 71 | success: true, 72 | message: "Wrong Password." 73 | }); 74 | } 75 | }); 76 | }); 77 | }); 78 | 79 | /** 80 | * Get Authenticated user profile 81 | */ 82 | 83 | router.get('/profile', passport.authenticate('jwt', { 84 | session: false 85 | }), (req, res) => { 86 | // console.log(req.user); 87 | return res.json( 88 | req.user 89 | ); 90 | }); 91 | 92 | module.exports = router; --------------------------------------------------------------------------------