node.js 中的用户角色和规则(权限)访问

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

我创建了一个 node.js 应用程序(巴士票预订应用程序)。 MongoDB 是我正在使用的数据库系统。我还没有完成前端。我正在使用 Postman 进行 API 查询。

对于身份验证,我使用 JWT。现在我想为应用程序的管理员、主管和普通用户等用户添加角色和规则。

1 -> 一个用户可以分配多个角色(管理员、主管)。

2 -> 可以将权限分配给角色(创建、更新、删除等...)。

因此,一个用户可以拥有一个或多个角色,每个角色可以拥有一个或多个权限。用户可以使用自己有权限的API,例如创建数据、删除数据、更新数据等。

这是用户架构:

const userSchema = new mongoose.Schema({
  firstname: {
    type: String,
    required: true,
  },
  lastname: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    unique: true,
    required: true,
    validate(value) {
      if (!validator.isEmail(value)) {
        throw new Error("Please provide the valid email address");
      }
    },
  },
  password: {
    type: String,
    required: true,
    trim: true,
    minLength: 8,
  },
  phone: {
    type: Number,
    required: true,
    unique: true
  },
  tokens:[{
    token: {
      type: String,
      required:true
    }
  }]
},{
  timestamps:true
});

我是新手,对此了解甚少。

有人可以帮助我吗?

node.js express roles
2个回答
8
投票

如果您只需要几个不同的角色, 我建议您采用 Sajawal Hassan 的概念,即简单地添加布尔字段来确定用户的访问级别。

但是,如果您计划创建要添加多个角色的位置,并且不希望为每个角色添加字段:

  1. 将权限数组字段添加到数据模型,并为用户数据模型创建权限列表(以更好地组织)
  2. 设置中间件以添加到您的路由器
  3. 设置组以允许路由器的用户,并通过路由器传递它们

1a。我建议您在用户模型文件中创建角色列表。可能是一本字典。

.../models/user.js

const ROLES = {
    ADMIN: "ADMIN",
    SUPERVISOR: "SUPERVISOR"
}
...
module.exports = mongoose.model('User', UserSchema);
module.exports.ROLES = ROLES;

1b。将数组字段添加到用户模型,该模型将具有角色作为权限

.../user.js

const userSchema = new mongoose.Schema({
    ...,
    permissions: [String],
    ...
});
  1. 设置中间件,或者在这种情况下您已经拥有身份验证;向函数添加功能,在该函数中它将检查其参数或将其附加到选项(如果您正在检查令牌或其他身份验证参数)

.../auth.js

module.exports = function (options) {
    ...
    // get user, validate token b4 here
    user.permissions.forEach(permission => {
        if (options.allowedGroup.indexOf(permission)){
            // if authenticated
            return next();
        }
    }
    // could not authenticate at this point
    return next(errorHandler) // throw a error or handle it way you want
}

3a。设置组以确定哪些角色可以访问每个路由器或一组路由器

.../routes/api_123.js

const mongoose = require('mongoose');
const User = mongoose.model('User');

const readGroup = [User.ROLES.SUPERVISOR, User.ROLES.ADMIN];
const writeGroup = [User.ROLES.ADMIN];

3b。将您创建的组作为 allowedGroup 传递到中间件的参数中,并使用 asyncHandler 进行设置

...
const asyncHandler = require('express-async-handler');
...

router.get('/user/:id', auth({allowedGroup: readGroup}), asyncHandler(async(req, res, next) => {
    ... // your stuff here
    res.status(200).json(data);
})) 

router.post('/user/:id', auth({allowedGroup: writeGroup}), asyncHandler(async(req, res, next) => {
    ... // your stuff here
    res.status(200).json(data);
})) 

2
投票

您应该尝试观看有关express和mongodb的完整课程,但是您必须在用户模式中添加字段来指定用户是否具有权限,即

admin: { type: booleen, default: false }
,然后如果您希望用户成为管理员,则将布尔值设置为true为只有管理员才能执行的操作创建一条路由,比如删除用户,然后检查用户模式中的管理字段是否为真。如果是这样,那么用户可以删除,否则抛出错误。

编辑:

请记住我使用 mongodb atlas 作为代码

添加一个管理字段(或者您想要的任何角色,我将在此处与管理员一起使用) 所以改变

const userSchema = new mongoose.Schema({
  firstname: {
    type: String,
    required: true,
  },
  lastname: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    unique: true,
    required: true,
    validate(value) {
      if (!validator.isEmail(value)) {
        throw new Error("Please provide the valid email address");
      }
    },
  },
  password: {
    type: String,
    required: true,
    trim: true,
    minLength: 8,
  },
  phone: {
    type: Number,
    required: true,
    unique: true
  },
  tokens:[{
    token: {
      type: String,
      required:true
    }
  }]
},{
  timestamps:true
});

到此

const userSchema = new mongoose.Schema({
  admin: {
    type: Booleen,
    default: false,
  },
  firstname: {
    type: String,
    required: true,
  },
  lastname: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    unique: true,
    required: true,
    validate(value) {
      if (!validator.isEmail(value)) {
        throw new Error("Please provide the valid email address");
      }
    },
  },
  password: {
    type: String,
    required: true,
    trim: true,
    minLength: 8,
  },
  phone: {
    type: Number,
    required: true,
    unique: true
  },
  tokens:[{
    token: {
      type: String,
      required:true
    }
  }]
},{
  timestamps:true
});

我刚刚在用户架构中添加了管理字段

然后假设您只希望管理员能够删除用户 为此,您必须创建这样的路线

router.delete("/delete/:id", async (req, res) => {
  try {
    // First find the user admin wants to delete
    const user = await User.findById(req.params.id) // getting id from the id you put in url

    // Make sure the user who wants to delete another user is an admin
    if (user.admin) {
       await user.deleteOne() // This deletes the user
    } else {
       res.status(403).json("You are not allowed to do this action!")
    }
  } catch (error) {
    res.sendStatus(500);
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.