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

发布于 2025-02-04 15:14:15 字数 1030 浏览 3 评论 0原文

我创建了一个Node.js应用程序(Bus-Ticket-Book Booking应用程序)。 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
});

我是新手,对此知识很少。

有人可以帮助我吗?

I created a node.js application (Bus-ticket-booking app). MongoDB is the database system I'm using. I haven't yet finished the front end. I'm doing API queries with Postman.

For authentication, I'm using JWT. Now I want to add roles and rules for users such as the app's administrator, supervisor, and normal user.

1 -> A user can have many roles assigned to them (admin, supervisor).

2 -> Permissions can be assigned to a role ( Create, Update, delete etc...).

As a result, a user can have one or more roles, and each role can have one or more permissions. A user can use APIs for which he has rights, such as creating data, deleting data, updating data, and so on.

Here is the user schema:

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
});

I'm new to it and have very little knowledge about it.

Is there anyone who can assist me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜妞爱困 2025-02-11 15:14:15

如果您只需要几个不同的角色,
我建议您使用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;将功能功能添加到将检查其参数或将其附加到选项的功能(如果您要检查令牌或其他auth params)

.../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。通过您作为中间件参数允许的组进行的组,并使用异步

...
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);
})) 

If you just need a couple different roles,
I suggest you go with Sajawal Hassan's concept of simply adding a boolean field to determine user's access level.

However, if you are planning to create where there are multitude of roles to be added, and do not want field to be added for each role:

  1. Add permissions array field to data model and create a permission list (to better organize) to the user data model
  2. set up a middleware to add to your routers
  3. set up groups to allow the user of your routers, and pass them through routers

1a. I suggest you create a list of roles within the user model file. Possibly a dictionary.

.../models/user.js

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

1b. add a array field to Users models which will have the roles as permissions

.../user.js

const userSchema = new mongoose.Schema({
    ...,
    permissions: [String],
    ...
});
  1. Set up a middleware or in this case you already have auth; add functional capabilities to the function in which it will check its parameter or attach it to options (if you are checking for token, or other auth params)

.../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. set up groups to determine which roles will have access to each router or a set of routers

.../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. pass the group you made as allowedGroup in param of middleware and set it up with a 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);
})) 
雨后咖啡店 2025-02-11 15:14:15

您应该尝试在Express和MongoDB上观看完整的课程,但是您必须在用户模式中添加字段,这些字段指定用户是否具有权限,即admin:{type:booleen,booleen,default:false}然后如果您希望用户成为管理用户,则将布莱恩设置为true,然后创建一个只能说admin的路由来删除用户,然后在那里检查用户架构中的管理字段是否为true。如果是这样,则用户可以删除,否则投掷错误。

编辑:

请记住,我使用MongoDB Atlas作为代码

添加Admin字段(或您想要的任何角色都会在此处使用Admin)
因此,

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);
  }
});

You should try to watch a full course on express and mongodb but you would have to add fields in the user schema that specifies if the user has permissions i.e admin: { type: booleen, default: false } then set the booleen to true if you want the user to be admin then create a route for something only admin sould be able to do lets say to delete a user so then in there check if the admin field in user schema is true. If so then user can delete otherwise throw err.

edit:

Do keep in mind im using mongodb atlas for the code

Add an admin field (or any role that you want im gonna go with admin here)
so change

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
});

to this

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
});

I just added the admin field in the user schema

Then lets say you only want the admin to be able to delete users
for that you would have to create a route like this

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);
  }
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文