This may be a terminology issue, and that is why I have been unable to find a solution. I am building a REST API inside express and I plan to use roles in the authorization step. What I am looking to know is if I can return a different json object based on the role of the logged in user which I can get from the headers.
As an example, if a logged in user has the supervisor role and calls api/colleagues/5, I would want a "limited" object returned such as
{
firstname: "John",
lastname: "smith",
contact: "01234567890"
}
However if the logged in user has the manager role and calls api/colleagues/5, I would want to return the "full" object with all keys, such as
{
firstname: "John",
lastname: "smith",
contact: "01234567890",
dob: "1970-01-01",
address: "123 Fake Street, Springfield"
}
Is this possible, and is this even "technically" allowed in REST. I have seen some answers where people had endpoints specifically for the situation i.e.
api/supervisor/colleagues/5 or
api/manager/colleagues/5.
It seemed they were looking more at outright access i.e. role A has access and role B does not, I don't believe that to be the best option for me.
Yes normally one end point with one specific function and it's either the role has access or not.
In your use case if you really want to have different response output base on your user role with one end point, you can achieve it. If you use jwt token to login, your jwt payload should contain the user role. On token verify, decoded token values add it in your request.
Sample Code:
verifyToken: async (req, res, next) => {
let token = req.headers['x-access-token'] || req.headers['authorization'];
if (token && token.startsWith('Bearer ')) {
// Remove Bearer from string
token = token.slice(7, token.length);
if (!token) return res.status(401).json({ errors: 'Token invalid' });
jwt.verify(token, 'YOUR_SECRET_API_KEY', (err, decoded) => {
if (err) {
return res.status(401).json({
errors: [{ err: 'Token invalid' }]
});
} else {
req.decoded = decoded;
next();
}
});
}
else {
return res.status(401).json({ errors: 'Token invalid' });
}
/* Sample decoded values in request
req.decoded = {
role: 'manager',
issuer: 'Issuer',
iat: 1707435705,
exp: 1707439305
} */
}
And in your Controller / Service, when you prepare the response output add role check and prepare response accordingly
getColleagues: async (req, res) => {
const { decoded } = req;
/**
* Execute your queries and other functionalities
* ......
* ................
* .....................
**/
if (success) { // Success
const data = {
firstname: 'John',
lastname: 'smith',
contact: '01234567890'
};
if (decoded.role === 'manager') {
res.dob = '1970-01-01';
res.address = '123 Fake Street, Springfield';
}
return res.status(200).json({ data: data });
} else { // Fail return error
return res.status(422).json({ errors: 'Something went wrong' });
}
}