I'm new to Express 4 and i'm wondering something about how to implement this thing: I'm using jwt to authenticate the consumer of my API, to do that i have a pretty simple middleware to check the validity of the jwt token:
var requireValidToken = function(req, res, next) {
var token = req.body.token || req.query.token || req.headers['x-access-token'];
if (token) {
try {
var decoded = jwt.verify(token, req.app.get('superSecret'));
} catch(err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
}
req.user = decoded.user;
next();
} else {
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
};
This is working pretty well, but now, i want to extend this to be able to check the role of the user:
router.get('/anAdminRoute', requireRole('ROLE_ADMIN'), function (req, res, next) {
// some code...
});
So i added a middleware for this:
var requireRole = function(role) {
return function(req, res, next){
// Dummy tests...
if(req.user.role == roles.admin || req.user.role == role){
next();
} else {
return res.status(403)({
success: false,
message: "Token valid, but you don't have the right permission to access this resource :)"
});
}
}
}
But as this requireRole() function while obviously checks for a valid jwt token, i'm wondering how can i call my requireValidToken middleware within this function, and so not having to explicitly call it for each route i want to protect.
An easy solution would have been not to use requireValidToken as a middleware but i still want to be able to use it to protect certain routes
Edit: Solution
Chaining middlewares is a simple as that:
var middleware2 = function(param) {
return function(req, res, next){
middleware1(req, res, function(){
// middleware2 code
});
}
}
If anybody interested, my final working solution to validate a user role:
var jwt = require('jsonwebtoken'),
roles = require('../models/user').roles;
// authentication middleware
// check if the given jwt token is valid
var requireValidToken = function(req, res, next) {
var token = req.body.token || req.query.token || req.headers['x-access-token'];
if (token) {
try {
var decoded = jwt.verify(token, req.app.get('superSecret'));
} catch(err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
}
req.user = decoded.user;
next();
} else {
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
};
var requireRole = function(role) {
return function(req, res, next){
requireValidToken(req, res, function(){
if(req.user.role == roles.admin || req.user.role == role){
next();
} else {
return res.status(403).send({
success: false,
message: "Token valid, but you don't have the right permission to access this resource :)"
});
}
});
}
}
module.exports = {
requireValidToken: requireValidToken,
requireRole: requireRole
}
Completely misread your question. If you want to call requireValidToken
for certain situations, you can pass along the req and res objects to the middleware function, along with an anonymous callback. How you get the middleware function largely depends on your application architecture so I'll assume I have the requireValidToken
within my context:
var requireRole = function(role) {
return function(req, res, next){
// Dummy tests...
requireValidToken(req, res, function () {
if(req.user.role == roles.admin || req.user.role == role){
next();
} else {
return res.status(403)({
success: false,
message: "Token valid, but you don't have the right permission to access this resource :)"
});
}
});
}
};
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