В моем NodeJS API я реализовал роли, используя этот npm pkg accesscontrol
, и также использовал JWT
для части токена. Моя проблема в том, что я не могу ограничить роль пользователя basi c для обновления учетной записи, которая не является его / ее собственной. Чего я хотел бы добиться, так это того, что Admin может делать все, что он хочет, но другие роли, такие как basi c, ограничены. В моем случае я хочу, чтобы пользователь с ролью basi c мог обновлять только свою учетную запись, но не другую, но теперь не работающую.
В моем Почтальоне я вызываю конечную точку обновления токеном роли basei c и пытаюсь обновить идентификатор пользователя, который не связан с токеном. То, что я должен увидеть, это сообщение, которое говорит You don't have enough permission to perform this action
, но вместо этого я могу обновить.
Роли, которые я использовал, это PKG AccessControl
// Access controls roles
const AccessControl = require("accesscontrol");
let grantsObject = {
admin: {
user: {
"create:any": ["*"],
"read:any": ["*"],
"update:any": ["*"],
"delete:any": ["*"]
}
},
basic: {
user: {
"create:own": ["*"],
"read:own": ["*"],
"update:own": ["*"],
"delete:own": ["*"],
}
}
};
// Init
const accessCtrl = new AccessControl();
// Roles access
// Here adding the access rules and to what we give access to a specific role
// Basic, Moderator, Admin
// Admin => Read/Write full powers
// Moderator => Read access everywhere
// Basic => Read/write own information
exports.roles = (() => {
accessCtrl.setGrants(grantsObject);
return accessCtrl;
})();
Мой route
// PUT update user
router.put(
"/:userId",
Auth.allowIfLoggedin,
Auth.grantAccess("updateOwn", "user"),
UserCtrl.updateUser
);
Используется промежуточное ПО:
/ Allowing access to right role permission
const grantAccess = (action, resource) => {
return async (req, res, next) => {
try {
console.log(req.user.role);
// Permission to perform the specified action of the provided resource
const permission = Roles.roles.can(req.user.role)[action](resource);
// No permission => 401
if (!permission.granted) {
throw new ErrorHandlers.ErrorHandler(
401,
"You don't have enough permission to perform this action"
);
}
next();
} catch (error) {
next(error);
}
};
};
// Allow if user logged in
const allowIfLoggedin = async (req, res, next) => {
try {
console.log("LOCALS", JSON.stringify(res.locals));
const user = res.locals.loggedInUser;
if (!user)
throw new ErrorHandlers.ErrorHandler(
401,
"You need to be logged in to perform this operation"
);
// User
req.user = user;
next();
} catch (error) {
next(error);
}
};
module.exports = { grantAccess, allowIfLoggedin };
Контроллер
// UPDATE user
async updateUser(req, res, next) {
try {
// Check empty req.body
if (Object.keys(req.body).length === 0) {
throw new ErrorHandlers.ErrorHandler(500, "Nothing to update");
}
// Body to update
const update = req.body;
// UserId to update
const userId = req.params.userId;
// Finding the user to update
await User.findByIdAndUpdate(userId, update);
// Updated user
const user = await User.findById(userId);
// Response
res.status(200).json({
user: user,
message: "User has been updated"
});
} catch (error) {
next(error);
}
},