From e312b19936941a6fb777495f7e6ac369febb989e Mon Sep 17 00:00:00 2001 From: Tien Nguyen Truong Date: Wed, 2 Dec 2020 11:05:12 +0700 Subject: [PATCH 1/2] add references --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 49808c7..a1ee130 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,11 @@ For more detail, please visit: Working with Front-end: > [Vue.js JWT Authentication with Vuex and Vue Router](https://bezkoder.com/jwt-vue-vuex-authentication/) -> [Angular 8 JWT Authentication with HttpInterceptor and Router](https://bezkoder.com/angular-jwt-authentication/) +> [Angular 8 JWT Authentication example](https://bezkoder.com/angular-jwt-authentication/) -> [Angular 10 JWT Authentication with HttpInterceptor and Router](https://bezkoder.com/angular-10-jwt-auth/) +> [Angular 10 JWT Authentication example](https://bezkoder.com/angular-10-jwt-auth/) + +> [Angular 11 JWT Authentication example](https://bezkoder.com/angular-11-jwt-auth/) > [React JWT Authentication & Authorization (without Redux) example](https://bezkoder.com/react-jwt-auth/) From bf1dbff2f159ba054dec2e339da22ee567f466dd Mon Sep 17 00:00:00 2001 From: zubair-saif Date: Tue, 12 Jan 2021 12:36:35 +0500 Subject: [PATCH 2/2] code improvement and remove body-parser and added new package --- .env | 2 + app/config/auth.config.js | 3 - app/config/db.config.js | 4 - app/controllers/auth.controller.js | 129 +++++++++++++++-------------- app/middleware/authJwt.js | 60 ++++++++------ app/middleware/verifySignUp.js | 49 +++++------ app/models/index.js | 10 +-- package.json | 4 +- server.js | 19 ++--- 9 files changed, 137 insertions(+), 143 deletions(-) create mode 100644 .env delete mode 100644 app/config/auth.config.js diff --git a/.env b/.env new file mode 100644 index 0000000..6d114ee --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +POSTGRES_URI=postgres://postgres:admin@localhost:5432/testdb +SESSION_SECRET=bezkoder-secret-key \ No newline at end of file diff --git a/app/config/auth.config.js b/app/config/auth.config.js deleted file mode 100644 index 4819df3..0000000 --- a/app/config/auth.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - secret: "bezkoder-secret-key" -}; diff --git a/app/config/db.config.js b/app/config/db.config.js index d186745..8a81fbe 100644 --- a/app/config/db.config.js +++ b/app/config/db.config.js @@ -1,8 +1,4 @@ module.exports = { - HOST: "localhost", - USER: "postgres", - PASSWORD: "123", - DB: "testdb", dialect: "postgres", pool: { max: 5, diff --git a/app/controllers/auth.controller.js b/app/controllers/auth.controller.js index ca4682a..141da6b 100644 --- a/app/controllers/auth.controller.js +++ b/app/controllers/auth.controller.js @@ -1,87 +1,92 @@ +const jwt = require("jsonwebtoken"); +const bcrypt = require("bcrypt"); const db = require("../models"); -const config = require("../config/auth.config"); const User = db.user; const Role = db.role; - const Op = db.Sequelize.Op; -var jwt = require("jsonwebtoken"); -var bcrypt = require("bcryptjs"); -exports.signup = (req, res) => { +exports.signup = async (req, res) => { // Save User to Database - User.create({ - username: req.body.username, - email: req.body.email, - password: bcrypt.hashSync(req.body.password, 8) - }) - .then(user => { + try { + const user = await User.create({ + username: req.body.username, + email: req.body.email, + password: bcrypt.hashSync(req.body.password, 10) + }); + if (user) { if (req.body.roles) { - Role.findAll({ + const role = await Role.findAll({ where: { name: { [Op.or]: req.body.roles } } - }).then(roles => { - user.setRoles(roles).then(() => { - res.send({ message: "User registered successfully!" }); - }); }); + if (role) { + await user.setRoles(roles) + res.send({ message: "User registered successfully!" }); + } + } else { // user role = 1 - user.setRoles([1]).then(() => { - res.send({ message: "User registered successfully!" }); - }); - } - }) - .catch(err => { - res.status(500).send({ message: err.message }); - }); -}; + const setRoles = await user.setRoles([1]); + res.send({ message: "User registered successfully!" }); -exports.signin = (req, res) => { - User.findOne({ - where: { - username: req.body.username - } - }) - .then(user => { - if (!user) { - return res.status(404).send({ message: "User Not found." }); } + } - var passwordIsValid = bcrypt.compareSync( - req.body.password, - user.password - ); + } catch (err) { + res.status(500).send({ message: err.message }); + } - if (!passwordIsValid) { - return res.status(401).send({ - accessToken: null, - message: "Invalid Password!" - }); + +}; + +exports.signin = async (req, res) => { + + try { + const user = await User.findOne({ + where: { + username: req.body.username } + }); + if (!user) { + return res.status(404).send({ message: "User Not found." }); + } - var token = jwt.sign({ id: user.id }, config.secret, { - expiresIn: 86400 // 24 hours - }); + const passwordIsValid = await bcrypt.compareSync( + req.body.password, + user.password + ); - var authorities = []; - user.getRoles().then(roles => { - for (let i = 0; i < roles.length; i++) { - authorities.push("ROLE_" + roles[i].name.toUpperCase()); - } - res.status(200).send({ - id: user.id, - username: user.username, - email: user.email, - roles: authorities, - accessToken: token - }); + if (!passwordIsValid) { + return res.status(401).send({ + accessToken: null, + message: "Invalid Password!" }); - }) - .catch(err => { - res.status(500).send({ message: err.message }); + } + + const token = await jwt.sign({ id: user.id }, process.env.SESSION_SECRET, { + expiresIn: 86400 // 24 hours }); -}; + + const authorities = []; + const roles = await user.getRoles() + if (roles) { + for (let i = 0; i < roles.length; i++) { + authorities.push("ROLE_" + roles[i].name.toUpperCase()); + } + res.status(200).send({ + id: user.id, + username: user.username, + email: user.email, + roles: authorities, + accessToken: token + }); + } + } catch (err) { + res.status(500).send({ message: err.message }); + } + +} diff --git a/app/middleware/authJwt.js b/app/middleware/authJwt.js index 2cbe752..4d92128 100644 --- a/app/middleware/authJwt.js +++ b/app/middleware/authJwt.js @@ -1,9 +1,9 @@ const jwt = require("jsonwebtoken"); -const config = require("../config/auth.config.js"); const db = require("../models"); const User = db.user; -verifyToken = (req, res, next) => { +verifyToken = async (req, res, next) => { + let token = req.headers["x-access-token"]; if (!token) { @@ -12,7 +12,7 @@ verifyToken = (req, res, next) => { }); } - jwt.verify(token, config.secret, (err, decoded) => { + jwt.verify(token, process.env.SESSION_SECRET, (err, decoded) => { if (err) { return res.status(401).send({ message: "Unauthorized!" @@ -23,44 +23,51 @@ verifyToken = (req, res, next) => { }); }; -isAdmin = (req, res, next) => { - User.findByPk(req.userId).then(user => { - user.getRoles().then(roles => { +isAdmin = async (req, res, next) => { + const user = await User.findByPk(req.userId); + if (user) { + const roles = await user.getRoles(); + if (roles) { for (let i = 0; i < roles.length; i++) { if (roles[i].name === "admin") { next(); return; } } - res.status(403).send({ message: "Require Admin Role!" }); return; - }); - }); -}; + } + } +} + +isModerator = async (req, res, next) => { -isModerator = (req, res, next) => { - User.findByPk(req.userId).then(user => { - user.getRoles().then(roles => { + const user = await User.findByPk(req.userId); + if (user) { + const roles = await user.getRoles(); + if (roles) { for (let i = 0; i < roles.length; i++) { if (roles[i].name === "moderator") { next(); return; } } - res.status(403).send({ message: "Require Moderator Role!" }); - }); - }); -}; + } + + } +} -isModeratorOrAdmin = (req, res, next) => { - User.findByPk(req.userId).then(user => { - user.getRoles().then(roles => { +isModeratorOrAdmin = async (req, res, next) => { + + const user = await User.findByPk(req.userId); + if (user) { + const roles = await user.getRoles(); + if (roles) { for (let i = 0; i < roles.length; i++) { if (roles[i].name === "moderator") { next(); @@ -71,14 +78,13 @@ isModeratorOrAdmin = (req, res, next) => { next(); return; } + res.status(403).send({ + message: "Require Moderator or Admin Role!" + }); } - - res.status(403).send({ - message: "Require Moderator or Admin Role!" - }); - }); - }); -}; + } + } +} const authJwt = { verifyToken: verifyToken, diff --git a/app/middleware/verifySignUp.js b/app/middleware/verifySignUp.js index 2e2e030..a83fa6e 100644 --- a/app/middleware/verifySignUp.js +++ b/app/middleware/verifySignUp.js @@ -2,37 +2,35 @@ const db = require("../models"); const ROLES = db.ROLES; const User = db.user; -checkDuplicateUsernameOrEmail = (req, res, next) => { +checkDuplicateUsernameOrEmail = async (req, res, next) => { // Username - User.findOne({ + const user = await User.findOne({ where: { username: req.body.username } - }).then(user => { - if (user) { - res.status(400).send({ - message: "Failed! Username is already in use!" - }); - return; - } - - // Email - User.findOne({ - where: { - email: req.body.email - } - }).then(user => { - if (user) { - res.status(400).send({ - message: "Failed! Email is already in use!" - }); - return; - } - - next(); + }); + if (user) { + res.status(400).send({ + message: "Failed! Username is already in use!" }); + return; + } + + // Email + const isfind = await User.findOne({ + where: { + email: req.body.email + } }); -}; + if (isfind) { + res.status(400).send({ + message: "Failed! Email is already in use!" + }); + return; + } + next(); +} + checkRolesExisted = (req, res, next) => { if (req.body.roles) { @@ -45,7 +43,6 @@ checkRolesExisted = (req, res, next) => { } } } - next(); }; diff --git a/app/models/index.js b/app/models/index.js index 99f94de..0aaa029 100644 --- a/app/models/index.js +++ b/app/models/index.js @@ -1,15 +1,11 @@ const config = require("../config/db.config.js"); - const Sequelize = require("sequelize"); + const sequelize = new Sequelize( - config.DB, - config.USER, - config.PASSWORD, + process.env.POSTGRES_URI, { - host: config.HOST, dialect: config.dialect, - operatorsAliases: false, - + operatorsAliases: 0, pool: { max: config.pool.max, min: config.pool.min, diff --git a/package.json b/package.json index 7b957cd..e7273c3 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,9 @@ "author": "bezkoder", "license": "ISC", "dependencies": { - "bcryptjs": "^2.4.3", - "body-parser": "^1.19.0", + "bcrypt": "^5.0.0", "cors": "^2.8.5", + "dotenv": "^8.2.0", "express": "^4.17.1", "jsonwebtoken": "^8.5.1", "pg": "^7.17.1", diff --git a/server.js b/server.js index c8e8642..18c7ae8 100644 --- a/server.js +++ b/server.js @@ -1,20 +1,15 @@ const express = require("express"); -const bodyParser = require("body-parser"); const cors = require("cors"); - +const config = require('dotenv').config(); const app = express(); -var corsOptions = { - origin: "http://localhost:8081" -}; - -app.use(cors(corsOptions)); +app.use(cors()); // parse requests of content-type - application/json -app.use(bodyParser.json()); +app.use(express.json()); // parse requests of content-type - application/x-www-form-urlencoded -app.use(bodyParser.urlencoded({ extended: true })); +app.use(express.urlencoded({ extended: true })); // database const db = require("./app/models"); @@ -22,7 +17,7 @@ const Role = db.role; // db.sequelize.sync(); // force: true will drop the table if it already exists -db.sequelize.sync({force: true}).then(() => { +db.sequelize.sync({ force: true }).then(() => { console.log('Drop and Resync Database with { force: true }'); initial(); }); @@ -47,12 +42,12 @@ function initial() { id: 1, name: "user" }); - + Role.create({ id: 2, name: "moderator" }); - + Role.create({ id: 3, name: "admin"