是否可以根据角色从同一端点返回不同的json

问题描述 投票:0回答:1

这可能是一个术语问题,这就是为什么我一直无法找到解决方案。我正在 Express 中构建 REST API,并计划在授权步骤中使用角色。我想知道的是,我是否可以根据登录用户的角色返回不同的 json 对象,我可以从标头中获取该对象。

举个例子,如果登录用户具有主管角色并调用 api/colleagues/5,我希望返回一个“有限”对象,例如

{
  firstname: "John",
  lastname: "smith",
  contact: "01234567890"
}

但是,如果登录用户具有经理角色并调用 api/colleagues/5,我想返回包含所有键的“完整”对象,例如

{
  firstname: "John",
  lastname: "smith",
  contact: "01234567890",
  dob: "1970-01-01",
  address: "123 Fake Street, Springfield"
}

这可能吗?这在 REST 中“技术上”是否允许?我看到了一些答案,人们有专门针对这种情况的端点,即

api/主管/同事/5 或

api/经理/同事/5.

他们似乎更多地关注直接访问权限,即角色 A 具有访问权限而角色 B 没有,我不认为这对我来说是最佳选择。

json express roles
1个回答
0
投票

是的,通常一个端点具有一项特定功能,并且该角色要么具有访问权限,要么不具有访问权限。

在您的用例中,如果您确实希望根据您的用户角色在一个端点上获得不同的响应输出,您可以实现它。如果您使用 jwt 令牌登录,您的 jwt 负载应包含用户角色。在令牌验证时,解码后的令牌值会将其添加到您的请求中。

示例代码:

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 
        } */
    }

在您的控制器/服务中,当您准备响应输出时,添加角色检查并相应地准备响应

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' });
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.