I am trying to authenticate a Node.js API with JSON Web Tokens. I could generate the token authenticate the users. Now I need to proptect my API based on the user roles. Here is how I route middleware to authenticate and check token.
var app = express();
var apiRoutes = express.Router();
apiRoutes.use(function (req, res, next) {
var token = req.body.token || req.param('token') || req.headers['x-access-token'];
if (token) {
jwt.verify(token, app.get('superSecret'), function (err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
req.decoded = decoded;
next();
}
});
} else {
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
apiRoutes.get('/check', function (req, res) {
//...
});
app.use('/api', apiRoutes);
This way, I protect the API say /api/check
. This can be accessed by admin user
only. Now I have another super user
who can access /api/validate
which the admin user
can't access. How can I protect /api/validate
only for super user
. Do I need to write one more middleware to do this?
Here is how I do the admin check now,
apiRoutes.post('/delete/:id',requireAdmin, function (req, res) {
//do the rest
};
function requireAdmin(req, res, next) {
var currentUserRole=".."; //get current user role
if('admin' == currentUserRole )
{
next();
}
else{
next(new Error("Permission denied."));
return;
}
};
Similarly requireSuperUser
function for super user check.Is this the right way to do admin/super user check?
Role-based authorization enables customer management of users and their roles independently from Payment Feature Services. Role-based authorization has a user registry that is not part of Payment Feature Services. This authorization is optional and does not replace the current model.
JWT authentication is a token-based stateless authentication mechanism. It is popularly used as a client-side-based stateless session, this means the server doesn't have to completely rely on a data store (or) database to save session information. JWTs can be encrypted, but they are typically encoded & signed.
To authenticate a user, a client application must send a JSON Web Token (JWT) in the authorization header of the HTTP request to your backend API. API Gateway validates the token on behalf of your API, so you don't have to add any code in your API to process the authentication.
User Registration API, where each user is assigned a Role. User Authentication, where valid users are retuned a JWT Token. Role-based access to specific API targets by means of providing a valid JWT Token.
When creating the JWT, you can provide your own payload as a private claim. E.g.:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"superUser": false
}
Same way you can perhaps list a set of user roles for the logged in user
{
"sub": "1234567890",
"name": "John Doe",
"roles": [
"ADMIN",
"SUPERUSER"
]
}
What is required then is to decode the token (best use express.js middleware for this authentication/authorization purpose) and check the roles and throw a HTTP 401 when it's not allowed. When it's allowed, call next();
to go ahead and enter the matching route.
Small example of such a possible middleware function:
function canAccess(req, res, next) {
checkAuthorization(req, function (err, authorized) {
if (err || !authorized) {
res.send({message: 'Unauthorized', status: 401});
}
next();
});
function checkAuthorization(req, callback) {
// jwt decode and actual authentication admin/superuser matching goes here..
}
}
router.use(canAccess);
For more information on JWT claims: https://jwt.io/introduction
For more information on expressjs middleware: https://expressjs.com/en/guide/using-middleware.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With