I have a MEAN stack app with a REST like api. I have two user types: user and admin. To sign the user in and keep the session i use jsonwebtoken jwt like this (simplified):
const jwt = require("jsonwebtoken");
//example user, normally compare pass, find user in db and return user
let user = { username: user.username, userType: user.userType };
const token = jwt.sign({ data: user }, secret, {
expiresIn: 604800 // 1 week
});
To protect my express routes from I do this:
in this example it is a "get user" route, the admin is ofc allowed to get information about any given user. The "normal" user is only allowed to get information about him/her -self, why i compare the requested username to the username decoded form the token.
let decodeToken = function (token) {
let decoded;
try {
decoded = jwt.verify(token, secret);
} catch (e) {
console.log(e);
}
return decoded;
}
// Get one user - admin full access, user self-access
router.get('/getUser/:username', (req, res, next) => {
let username = req.params.username;
if (req.headers.authorization) {
let token = req.headers.authorization.replace(/^Bearer\s/, '');
decoded = decodeToken(token);
if (decoded.data.userType == 'admin') {
//do something admin only
} else if (decoded.data.username == username) {
//do something user (self) only
} else{
res.json({ success: false, msg: 'not authorized' });
}
} else {
res.json({ success: false, msg: 'You are not logged in.' });
}
})
So my question is, how secure is this? Could someone manipulate the session token to swap the username to someone else's username? or even change the userType from user to admin?
My guess is. Only if they know the "secret" but is that enough security? the secret is after all just like a plain text password stored in the code. What is best practice?