From 3eefb9fc74e4834cbd6cf0de63fc289d6f05839b Mon Sep 17 00:00:00 2001 From: I Kadek Yuda Budipratama Giri <13516115@std.stei.itb.ac.id> Date: Sun, 31 Mar 2019 17:07:52 +0700 Subject: [PATCH] Added extending token features --- backend/controller/authController.js | 15 +++++--- backend/controller/testController.js | 4 +-- .../20190329134047-add-jwt-column-to-user.js | 27 +++++++++++++++ backend/models/user.js | 3 +- backend/router/jwtTokenHandler.js | 34 +++++++++++++++++++ backend/router/router.js | 7 ++-- backend/router/verifyJwtToken.js | 21 +++++++++--- backend/router/verifySignUp.js | 1 - 8 files changed, 97 insertions(+), 15 deletions(-) create mode 100644 backend/migrations/20190329134047-add-jwt-column-to-user.js create mode 100644 backend/router/jwtTokenHandler.js diff --git a/backend/controller/authController.js b/backend/controller/authController.js index e9bfcb4..9332a63 100644 --- a/backend/controller/authController.js +++ b/backend/controller/authController.js @@ -54,10 +54,17 @@ exports.signin = (req, res) => { var token = jwt.sign({id: user.id}, config.secret, { expiresIn: config.jwtExpireTime }); - - res.status(200).send({ - auth: true, - accessToken: token + + User.update( + {validToken: token}, + {where: {id: user.id}} + ).then(() => { + res.status(200).send({ + auth: true, + accessToken: token + }); + }).error(() => { + res.status(500).send("Error saving new token"); }); }).catch(err => { res.status(500).send('Error -> ' + err); diff --git a/backend/controller/testController.js b/backend/controller/testController.js index a1752d6..4cd0325 100644 --- a/backend/controller/testController.js +++ b/backend/controller/testController.js @@ -6,7 +6,7 @@ const Role = models.role; exports.memberContent = (req, res) => { User.findOne({ where: { - id: req.userId + id: res.locals.userId }, attributes: ['id', 'name', 'username', 'email'], include: [{ @@ -21,7 +21,7 @@ exports.memberContent = (req, res) => { }).catch(err => { res.status(500).json({ "description": "Can not access User Page", - "error": er + "error": err.message }); }) } diff --git a/backend/migrations/20190329134047-add-jwt-column-to-user.js b/backend/migrations/20190329134047-add-jwt-column-to-user.js new file mode 100644 index 0000000..75e0498 --- /dev/null +++ b/backend/migrations/20190329134047-add-jwt-column-to-user.js @@ -0,0 +1,27 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.createTable('users', { id: Sequelize.INTEGER }); + */ + return queryInterface.addColumn('users', 'validToken', { + type: Sequelize.STRING + }); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + return queryInterface.removeColumn('users', 'validToken'); + } +}; diff --git a/backend/models/user.js b/backend/models/user.js index 93a0213..2290017 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -4,7 +4,8 @@ module.exports = (sequelize, DataTypes) => { name: DataTypes.STRING, email: DataTypes.STRING, password: DataTypes.STRING, - username: DataTypes.STRING + username: DataTypes.STRING, + validToken: DataTypes.STRING }, {}); user.associate = function(models) { models.user.belongsTo(models.role); diff --git a/backend/router/jwtTokenHandler.js b/backend/router/jwtTokenHandler.js new file mode 100644 index 0000000..0367932 --- /dev/null +++ b/backend/router/jwtTokenHandler.js @@ -0,0 +1,34 @@ +const jwt = require('jsonwebtoken'); +const config = require('../config/app.config.js'); +const models = require('../models'); +const User = models.user; + +extendJwtToken = (req, res, next) => { + var userId = res.locals.userId; + var token = jwt.sign({id: userId}, config.secret, { + expiresIn: config.jwtExpireTime + }); + res.locals.token = token; + next(); +} + +saveTokenToUser = (req, res, next) => { + token = res.locals.token; + userId = res.locals.userId; + User.update({ + validToken: token + }, { + where: { + id: userId + } + }).then(() => { + next(); + }); +} + +const jwtTokenHandler = {}; + +jwtTokenHandler.extendJwtToken = extendJwtToken; +jwtTokenHandler.saveTokenToUser = saveTokenToUser; + +module.exports = jwtTokenHandler; \ No newline at end of file diff --git a/backend/router/router.js b/backend/router/router.js index 21eb47b..dd5efcd 100644 --- a/backend/router/router.js +++ b/backend/router/router.js @@ -1,5 +1,6 @@ const verifySignUp = require('./verifySignUp'); -const authJwt = require('./verifyJwtToken'); +const verifyJwtToken = require('./verifyJwtToken'); +const tokenHandler = require('./jwtTokenHandler'); module.exports = function(app) { const authController = require('../controller/authController.js'); @@ -7,6 +8,6 @@ module.exports = function(app) { app.post('/api/auth/signup', [verifySignUp.checkDuplicateUserNameOrEmail, verifySignUp.checkRolesExisted], authController.signup); app.post('/api/auth/login', authController.signin); - app.get('/api/test/admin', [authJwt.verifyToken, authJwt.isAdmin], testController.adminContent); - app.get('/api/test/member', [authJwt.verifyToken], testController.memberContent); + app.get('/api/test/admin', [verifyJwtToken.verifyToken, verifyJwtToken.isAdmin, tokenHandler.extendJwtToken, tokenHandler.saveTokenToUser], testController.adminContent); + app.get('/api/test/member', [verifyJwtToken.verifyToken, tokenHandler.extendJwtToken, tokenHandler.saveTokenToUser], testController.memberContent); } \ No newline at end of file diff --git a/backend/router/verifyJwtToken.js b/backend/router/verifyJwtToken.js index c2b079e..5471b30 100644 --- a/backend/router/verifyJwtToken.js +++ b/backend/router/verifyJwtToken.js @@ -21,16 +21,29 @@ verifyToken = (req, res, next) => { auth: false }); } - req.userId = decoded.id; - next(); + res.locals.userId = decoded.id; + + // check if token is same + User.findOne({ + where: { + id: decoded.id + } + }).then(user => { + if (user.validToken === token) { + next(); + } else { + res.status(403).send("Cannot match token!"); + } + }); }); } isAdmin = (req, res, next) => { - User.findByPk(req.userId) + User.findByPk(res.locals.userId) .then(user => { user.getRole().then(role => { - if (role === 'Master Admin Diskominfo' || role === 'Admin Diskominfo' || role === 'Admin Dinas') { + if (role.name === 'Master Admin Diskominfo' || role.name === 'Admin Diskominfo' || role.name === 'Admin Dinas') { + res.locals.userId = res.locals.userId; next(); return; } diff --git a/backend/router/verifySignUp.js b/backend/router/verifySignUp.js index e6727cb..e105d61 100644 --- a/backend/router/verifySignUp.js +++ b/backend/router/verifySignUp.js @@ -33,7 +33,6 @@ checkRolesExisted = (req, res, next) => { res.status(400).send("Fail -> Role does NOT exist = " + req.body.role); return; } - next(); } -- GitLab