Nodejs 用 node.js+MongoDB做一个权限系统

Nodejs 用 node.js+MongoDB做一个权限系统

问题:目前想用node.js+MongoDB做一个通用权限系统,大家给点MongoDB数据库的设计思路嘛?

6 回复

当然可以。下面是一个简单的 Node.js 和 MongoDB 权限系统的实现方案。我们将设计一个基本的权限系统,包括用户、角色和权限。

数据库设计

用户 (User)

  • _id (ObjectId): 唯一标识符
  • username (String): 用户名
  • password (String): 密码(通常会进行哈希处理)
  • roles (Array): 用户所属的角色

角色 (Role)

  • _id (ObjectId): 唯一标识符
  • name (String): 角色名称
  • permissions (Array): 角色拥有的权限

权限 (Permission)

  • _id (ObjectId): 唯一标识符
  • name (String): 权限名称
  • description (String): 权限描述

示例代码

安装依赖

首先,确保安装了必要的依赖:

npm install express mongoose bcryptjs jsonwebtoken

MongoDB 模型定义

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const userSchema = new mongoose.Schema({
    username: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    roles: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Role' }]
});

const roleSchema = new mongoose.Schema({
    name: { type: String, required: true, unique: true },
    permissions: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Permission' }]
});

const permissionSchema = new mongoose.Schema({
    name: { type: String, required: true, unique: true },
    description: String
});

const User = mongoose.model('User', userSchema);
const Role = mongoose.model('Role', roleSchema);
const Permission = mongoose.model('Permission', permissionSchema);

module.exports = { User, Role, Permission };

创建用户、角色和权限

const { User, Role, Permission } = require('./models');

async function createEntities() {
    const adminRole = new Role({ name: 'admin' });
    await adminRole.save();

    const editorRole = new Role({ name: 'editor' });
    await editorRole.save();

    const readPermission = new Permission({ name: 'read', description: 'Can read data' });
    await readPermission.save();

    const writePermission = new Permission({ name: 'write', description: 'Can write data' });
    await writePermission.save();

    adminRole.permissions.push(readPermission._id, writePermission._id);
    await adminRole.save();

    editorRole.permissions.push(readPermission._id);
    await editorRole.save();

    const hashedPassword = await bcrypt.hash('password123', 10);
    const user = new User({
        username: 'admin',
        password: hashedPassword,
        roles: [adminRole._id]
    });
    await user.save();
}

createEntities().catch(console.error);

验证用户权限

const jwt = require('jsonwebtoken');
const { User, Role, Permission } = require('./models');

function authenticateToken(req, res, next) {
    const token = req.header('Authorization').split(' ')[1];
    if (!token) return res.sendStatus(401);

    jwt.verify(token, process.env.JWT_SECRET, async (err, user) => {
        if (err) return res.sendStatus(403);

        const foundUser = await User.findById(user.id).populate('roles');
        req.user = foundUser;
        next();
    });
}

app.get('/protected', authenticateToken, async (req, res) => {
    const { user } = req;

    // 检查用户是否具有特定权限
    const hasReadPermission = user.roles.some(role => 
        role.permissions.includes(somePermissionId)
    );

    if (hasReadPermission) {
        res.send('You have the read permission.');
    } else {
        res.status(403).send('Access denied.');
    }
});

以上是一个简单的 Node.js 和 MongoDB 权限系统的实现。你可以根据具体需求进行扩展和优化。


本人 比较菜,直接是数据库用了个type 来判断…

这个不够用,既然是一个权限系统,就要粒度细点.

跟用sql有大的区别么?你就把一个集合当成一个表,只是不能连表查询,需要多次查询而已

怎么发不了贴?

要在Node.js中使用MongoDB创建一个通用的权限系统,你需要设计一个合理的数据模型来存储用户、角色和权限。以下是一种可能的设计思路:

数据库设计

  1. 用户(Users)

    • 字段:_id(MongoDB自动生成),username(用户名),password(密码,建议存储哈希值),email(邮箱)等。
  2. 角色(Roles)

    • 字段:_id(MongoDB自动生成),name(角色名称),permissions(权限列表,包含一系列字符串,例如["read", "write"])。
  3. 权限(Permissions)

    • 权限可以直接定义在角色里,也可以单独定义一个集合来管理,这样可以更加灵活地分配权限。

示例代码

用户模型(users.js)

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    username: { type: String, required: true },
    password: { type: String, required: true }, // 应该使用哈希存储
    email: { type: String, required: true },
    roles: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Role' }] // 用户关联的角色
});

module.exports = mongoose.model('User', userSchema);

角色模型(roles.js)

const mongoose = require('mongoose');

const roleSchema = new mongoose.Schema({
    name: { type: String, required: true, unique: true },
    permissions: [{ type: String }] // 如:["create", "read", "update", "delete"]
});

module.exports = mongoose.model('Role', roleSchema);

权限验证中间件(authMiddleware.js)

const jwt = require('jsonwebtoken');
const User = require('./models/users');

function auth(req, res, next) {
    const token = req.headers['authorization'];
    if (!token) return res.status(401).send({ message: 'Unauthorized: No token provided.' });

    jwt.verify(token, process.env.SECRET_KEY, async (err, decoded) => {
        if (err) return res.status(401).send({ message: 'Unauthorized: Invalid token.' });
        
        const user = await User.findById(decoded.id);
        if (!user) return res.status(401).send({ message: 'Unauthorized: User not found.' });

        // 检查当前用户是否有权限执行当前操作
        const hasPermission = user.roles.some(roleId => {
            // 假设有一个角色对象中的权限字段与请求路径匹配
            return role.permissions.includes(req.path); 
        });

        if (!hasPermission) {
            return res.status(403).send({ message: 'Forbidden: You do not have the required permissions.' });
        }

        req.user = user;
        next();
    });
}

module.exports = auth;

这个设计提供了一个基础框架,你可以根据具体需求进行调整和扩展。

回到顶部