← 目录从零开始学习React

多用户权限管理系统项目实现

2024/9/22

构建一个复杂的多用户权限管理系统需要结合微前端架构、实时数据更新、用户认证和安全策略等技术。以下是一个详细的设计方案,包括系统架构、主要模块、技术栈以及具体实现步骤。


系统架构

1. 总体架构

text
multi-user-permission-system/
├── main-app/                 # 主应用
│   ├── src/
│   │   ├── App.js            # 主应用入口
│   │   ├── routes.js         # 路由配置
│   │   └── store.js          # 全局状态管理
├── user-management/          # 用户管理子应用
│   ├── src/
│   │   ├── App.js            # 子应用入口
│   │   └── components/       # 子应用组件
├── role-management/          # 角色管理子应用
│   ├── src/
│   │   ├── App.js            # 子应用入口
│   │   └── components/       # 子应用组件
├── permissions-management/    # 权限管理子应用
│   ├── src/
│   │   ├── App.js            # 子应用入口
│   │   └── components/       # 子应用组件
├── shared/                   # 共享模块
│   ├── components/           # 共享组件
│   └── utils/                # 共享工具函数
└── server/                   # 后端服务
    ├── src/
    │   ├── index.js          # 入口
    │   ├── routes/           # API 路由
    │   ├── controllers/      # 控制器
    │   ├── models/           # 数据模型
    │   └── socket.js         # WebSocket 实现

2. 技术栈

  • 前端:

    • React + React Router
    • Single SPA 或 Module Federation (Webpack 5)
    • Redux 或 Context API 进行状态管理
    • Material-UI 或 Ant Design 用于 UI 组件
    • Axios 用于 HTTP 请求
  • 后端:

    • Node.js + Express
    • MongoDB 或 PostgreSQL 作为数据库
    • JWT(JSON Web Token)进行用户认证
    • Socket.IO 用于实时数据更新
  • CI/CD:

    • GitHub Actions 或 Jenkins 进行自动化构建与部署
    • Docker 容器化部署

实现步骤

1. 后端实现

创建 Node.js 后端服务

bash
mkdir server && cd server
npm init -y
npm install express mongoose jsonwebtoken bcrypt socket.io cors

基本结构

js
// server/src/index.js
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const http = require('http');
const socketIo = require('socket.io');
const routes = require('./routes');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

app.use(cors());
app.use(express.json());
app.use('/api', routes);

mongoose.connect('mongodb://localhost:27017/permission_system', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

io.on('connection', (socket) => {
  console.log('New client connected');

  socket.on('disconnect', () => {
    console.log('Client disconnected');
  });
});

server.listen(5000, () => {
  console.log('Server is running on http://localhost:5000');
});

用户模型和认证

js
// server/src/models/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

const UserSchema = new mongoose.Schema({
  username: { type: String, unique: true },
  password: String,
  roles: [String], // 例如 ['admin', 'editor']
});

UserSchema.pre('save', async function(next) {
  if (this.isModified('password')) {
    this.password = await bcrypt.hash(this.password, 10);
  }
  next();
});

UserSchema.methods.comparePassword = function(password) {
  return bcrypt.compare(password, this.password);
};

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

用户注册与登录

js
// server/src/routes/auth.js
const express = require('express');
const User = require('../models/User');
const jwt = require('jsonwebtoken');

const router = express.Router();

router.post('/register', async (req, res) => {
  const { username, password } = req.body;
  const user = new User({ username, password });
  await user.save();
  res.status(201).send({ message: 'User registered' });
});

router.post('/login', async (req, res) => {
  const { username, password } = req.body;
  const user = await User.findOne({ username });
  if (!user || !(await user.comparePassword(password))) {
    return res.status(401).send({ message: 'Invalid credentials' });
  }
  const token = jwt.sign({ id: user._id, roles: user.roles }, 'secret_key');
  res.send({ token });
});

module.exports = router;

2. 前端实现

主应用配置

bash
mkdir main-app && cd main-app
npx create-react-app . --template typescript
npm install single-spa react-router-dom axios

主应用入口

tsx
// main-app/src/App.tsx
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import UserManagement from 'user-management';
import RoleManagement from 'role-management';
import PermissionsManagement from 'permissions-management';

const App: React.FC = () => {
  return (
    <Router>
      <Switch>
        <Route path="/users" component={UserManagement} />
        <Route path="/roles" component={RoleManagement} />
        <Route path="/permissions" component={PermissionsManagement} />
      </Switch>
    </Router>
  );
};

export default App;

子应用实现

在每个子应用中(如 user-management),使用 React Router 处理内部路由,并通过 Axios 与后端 API 通信。

tsx
// user-management/src/App.tsx
import React, { useState, useEffect } from 'react';
import axios from 'axios';

const UserManagement: React.FC = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const { data } = await axios.get('http://localhost:5000/api/users');
      setUsers(data);
    };
    fetchUsers();
  }, []);

  return (
    <div>
      <h1>User Management</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.username}</li>
        ))}
      </ul>
    </div>
  );
};

export default UserManagement;

3. 实时数据更新

Socket.IO 配置

在后端和前端都需要配置 Socket.IO,以实现实时数据更新。

后端 Socket.IO 实现

js
// server/src/socket.js
const io = require('socket.io')(server);

io.on('connection', (socket) => {
  console.log('New client connected');

  socket.on('updateUser', (userData) => {
    // 广播用户更新信息
    io.emit('userUpdated', userData);
  });
});

前端 Socket.IO 实现

tsx
// user-management/src/App.tsx
import io from 'socket.io-client';

const socket = io('http://localhost:5000');

useEffect(() => {
  socket.on('userUpdated', (userData) => {
    setUsers(prevUsers => prevUsers.map(user => user.id === userData.id ? userData : user));
  });
}, []);

4. 权限管理

通过角色和权限来控制用户访问,确保不同角色的用户访问不同的功能和数据。

权限中间件

js
// server/src/middleware/auth.js
const jwt = require('jsonwebtoken');

const authMiddleware = (req, res, next) => {
  const token = req.headers['authorization'];
  if (!token) return res.sendStatus(401);
  jwt.verify(token, 'secret_key', (err, decoded) => {
    if (err) return res.sendStatus(403);
    req.user = decoded;
    next();
  });
};

module.exports = authMiddleware;

路由保护

在特定的 API 路由中使用权限中间件来保护路由。

js
// server/src/routes/users.js
const express = require('express');
const authMiddleware = require('../middleware/auth');
const router = express.Router();

router.get('/', authMiddleware, async (req, res) => {
  // 根据用户角色返回不同的用户数据
});

5. CI/CD 和 Docker

Dockerfile

创建 Dockerfile 来容器化后端服务和前端应用。

dockerfile
# Dockerfile for backend
FROM node:14
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "src/index.js"]
dockerfile
# Dockerfile for frontend
FROM node:14 AS build
WORKDIR /app
COPY . .
RUN npm install && npm run build

FROM nginx:al

pine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

CI/CD

使用 GitHub Actions 或 Jenkins 设置 CI/CD 流程,确保每次提交代码后都能自动构建和部署应用。


总结

这个复杂的多用户权限管理系统示例结合了以下关键点:

  • 微前端架构:通过分离用户管理、角色管理和权限管理模块,提升系统的可维护性和可扩展性。
  • 实时数据更新:使用 Socket.IO 实现实时通知,确保用户界面动态更新。
  • 安全策略:通过 JWT 认证和权限中间件,确保系统安全。
  • CI/CD 和 Docker:容器化和自动化部署简化了开发和维护流程。

这样的架构不仅可以满足当前需求,还具备良好的扩展性,能够支持未来的功能需求和用户增长。