Files
laravel_swoole/docs/README_AUTH.md
2026-02-08 22:38:13 +08:00

639 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Auth 基础模块文档
## 概述
Auth 基础模块提供了完整的后台管理系统的认证授权功能,包括用户管理、角色管理、权限管理、部门管理等功能。
## 控制器结构
```
app/Http/Controllers/Auth/
└── Admin/
├── Auth.php # 认证控制器
├── User.php # 用户管理控制器
├── Role.php # 角色管理控制器
├── Permission.php # 权限管理控制器
└── Department.php # 部门管理控制器
```
**命名空间**: `App\Http\Controllers\Auth\Admin`
**路由前缀**: `/admin`
**中间件**: `auth.check:admin` (后台管理认证)
## 技术栈
- PHP 8.1+
- Laravel 11
- JWT 认证 (tymon/jwt-auth)
- Redis 缓存
- Laravel Excel (maatwebsite/excel)
## 数据库表结构
### auth_users (用户表)
- `id`: 主键
- `username`: 用户名(唯一)
- `password`: 密码(加密)
- `real_name`: 真实姓名
- `email`: 邮箱
- `phone`: 手机号
- `avatar`: 头像
- `department_id`: 部门ID
- `status`: 状态0:禁用, 1:启用)
- `last_login_at`: 最后登录时间
- `last_login_ip`: 最后登录IP
- `last_active_at`: 最后活跃时间
- `created_at`, `updated_at`: 时间戳
### auth_roles (角色表)
- `id`: 主键
- `name`: 角色名称
- `code`: 角色编码(唯一)
- `description`: 角色描述
- `sort`: 排序
- `status`: 状态
- `created_at`, `updated_at`: 时间戳
### auth_permissions (权限表)
- `id`: 主键
- `name`: 权限名称
- `code`: 权限编码(唯一,格式:模块.功能.操作)
- `type`: 类型menu:菜单, api:接口, button:按钮)
- `route`: 路由
- `component`: 组件路径
- `icon`: 图标
- `parent_id`: 父级ID
- `meta`: 元数据JSON格式
- `sort`: 排序
- `status`: 状态
- `created_at`, `updated_at`: 时间戳
### auth_role_permission (角色权限关联表)
- `id`: 主键
- `role_id`: 角色ID
- `permission_id`: 权限ID
### auth_user_role (用户角色关联表)
- `id`: 主键
- `user_id`: 用户ID
- `role_id`: 角色ID
### auth_departments (部门表)
- `id`: 主键
- `name`: 部门名称
- `parent_id`: 父级ID
- `leader`: 负责人
- `phone`: 联系电话
- `sort`: 排序
- `status`: 状态
- `created_at`, `updated_at`: 时间戳
## API 接口文档
### 中间件说明
### AuthCheckMiddleware
这是一个通用的认证中间件,支持通过参数指定不同的路由守卫和权限验证。
#### 基本用法
**1. 只进行登录认证(不检查权限)**
```php
// 使用 admin 守卫
Route::middleware(['auth.check:admin'])->group(function () {
Route::get('/users', [UserController::class, 'index']);
});
// 使用 api 守卫
Route::middleware(['auth.check:api'])->group(function () {
Route::get('/profile', [UserController::class, 'profile']);
});
```
**2. 登录认证 + 权限验证**
```php
// 验证用户是否有特定权限
Route::middleware(['auth.check:admin,system.user.list'])->group(function () {
Route::get('/users', [UserController::class, 'index']);
});
// 验证多个权限
Route::middleware(['auth.check:admin,system.user.create'])->group(function () {
Route::post('/users', [UserController::class, 'store']);
});
```
**3. 单个路由应用中间件**
```php
Route::middleware('auth.check:admin,system.user.delete')->delete('/users/{id}', [UserController::class, 'destroy']);
```
#### 参数说明
- `guard`: 认证守卫名称(必需),例如:`admin``api`
- `permission`: 权限编码(可选),如果指定则会验证用户是否有该权限
#### 功能特性
- ✅ 支持多个路由守卫admin、api等
- ✅ 支持登录状态检查
- ✅ 支持用户状态检查(禁用用户无法访问)
- ✅ 支持权限验证
- ✅ 自动将用户信息注入到请求中($request->auth_user
- ✅ 自动更新用户最后活跃时间
#### 认证相关
#### 登录
- **接口**: `POST /admin/auth/login`
- **参数**:
```json
{
"username": "admin",
"password": "123456"
}
```
- **返回**:
```json
{
"code": 200,
"message": "登录成功",
"data": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {...},
"menu": {...},
"permissions": {...}
}
}
```
#### 登出
- **接口**: `POST /admin/auth/logout`
- **Header**: `Authorization: Bearer {token}`
#### 刷新Token
- **接口**: `POST /admin/auth/refresh`
- **Header**: `Authorization: Bearer {token}`
#### 获取当前用户信息
- **接口**: `GET /admin/auth/me`
- **Header**: `Authorization: Bearer {token}`
#### 修改密码
- **接口**: `POST /admin/auth/change-password`
- **参数**:
```json
{
"old_password": "123456",
"new_password": "654321"
}
```
### 用户管理
#### 获取用户列表
- **接口**: `GET /admin/users`
- **参数**:
- `page`: 页码默认1
- `page_size`: 每页数量默认20
- `keyword`: 搜索关键词(用户名/真实姓名/邮箱)
- `status`: 状态0:禁用, 1:启用)
- `department_id`: 部门ID
- `role_id`: 角色ID
- `order_by`: 排序字段默认id
- `order_direction`: 排序方向asc/desc默认asc
#### 获取用户详情
- **接口**: `GET /admin/users/{id}`
#### 创建用户
- **接口**: `POST /admin/users`
- **参数**:
```json
{
"username": "test001",
"password": "123456",
"real_name": "测试用户",
"email": "test@example.com",
"phone": "13800138000",
"department_id": 1,
"role_ids": [1, 2],
"status": 1
}
```
#### 更新用户
- **接口**: `PUT /admin/users/{id}`
- **参数**: 同创建用户(所有字段都是可选的)
#### 删除用户
- **接口**: `DELETE /admin/users/{id}`
#### 批量删除用户
- **接口**: `POST /admin/users/batch-delete`
- **参数**:
```json
{
"ids": [1, 2, 3]
}
```
#### 批量更新用户状态
- **接口**: `POST /admin/users/batch-status`
- **参数**:
```json
{
"ids": [1, 2, 3],
"status": 1
}
```
#### 批量分配部门
- **接口**: `POST /admin/users/batch-department`
- **参数**:
```json
{
"ids": [1, 2, 3],
"department_id": 1
}
```
#### 批量分配角色
- **接口**: `POST /admin/users/batch-roles`
- **参数**:
```json
{
"ids": [1, 2, 3],
"role_ids": [1, 2]
}
```
#### 导出用户
- **接口**: `POST /admin/users/export`
- **参数**:
```json
{
"ids": [1, 2, 3] // 可选,不传则导出所有用户
}
```
#### 导入用户
- **接口**: `POST /admin/users/import`
- **参数**: `file` (multipart/form-data, xlsx/xls文件)
- **返回**:
```json
{
"code": 200,
"message": "导入完成,成功 10 条,失败 0 条",
"data": {
"success_count": 10,
"error_count": 0,
"errors": []
}
}
```
#### 下载用户导入模板
- **接口**: `GET /admin/users/download-template`
### 在线用户管理
#### 获取在线用户数量
- **接口**: `GET /admin/online-users/count`
#### 获取在线用户列表
- **接口**: `GET /admin/online-users`
- **参数**:
- `limit`: 数量限制默认100
#### 获取用户的所有会话
- **接口**: `GET /admin/online-users/{userId}/sessions`
#### 强制用户下线(单个会话)
- **接口**: `POST /admin/online-users/{userId}/offline`
- **参数**:
```json
{
"token": "用户token"
}
```
#### 强制用户所有设备下线
- **接口**: `POST /admin/online-users/{userId}/offline-all`
### 角色管理
#### 获取角色列表
- **接口**: `GET /admin/roles`
- **参数**:
- `page`, `page_size`, `keyword`, `status`, `order_by`, `order_direction`
#### 获取所有角色(不分页)
- **接口**: `GET /admin/roles/all`
#### 获取角色详情
- **接口**: `GET /admin/roles/{id}`
#### 创建角色
- **接口**: `POST /admin/roles`
- **参数**:
```json
{
"name": "编辑",
"code": "editor",
"description": "编辑角色",
"sort": 1,
"status": 1,
"permission_ids": [1, 2, 3]
}
```
#### 更新角色
- **接口**: `PUT /admin/roles/{id}`
#### 删除角色
- **接口**: `DELETE /admin/roles/{id}`
#### 批量删除角色
- **接口**: `POST /admin/roles/batch-delete`
#### 批量更新角色状态
- **接口**: `POST /admin/roles/batch-status`
#### 分配权限
- **接口**: `POST /admin/roles/{id}/permissions`
- **参数**:
```json
{
"permission_ids": [1, 2, 3]
}
```
#### 获取角色的权限列表
- **接口**: `GET /admin/roles/{id}/permissions`
#### 复制角色
- **接口**: `POST /admin/roles/{id}/copy`
- **参数**:
```json
{
"name": "新角色名称",
"code": "new_role_code",
"description": "新角色描述",
"status": 1
}
```
#### 批量复制角色
- **接口**: `POST /admin/roles/batch-copy`
- **参数**:
```json
{
"ids": [1, 2, 3],
"name": "新角色名称(可选)",
"code": "new_code可选"
}
```
### 权限管理
#### 获取权限列表
- **接口**: `GET /admin/permissions`
- **参数**:
- `page`, `page_size`, `keyword`, `type`, `status`, `order_by`, `order_direction`
#### 获取权限树
- **接口**: `GET /admin/permissions/tree`
#### 获取菜单树
- **接口**: `GET /admin/permissions/menu`
- **返回**: 当前登录用户的菜单树
#### 获取权限详情
- **接口**: `GET /admin/permissions/{id}`
#### 创建权限
- **接口**: `POST /admin/permissions`
- **参数**:
```json
{
"name": "用户列表",
"code": "system.user.list",
"type": "api",
"route": "/admin/users",
"component": "",
"icon": "user",
"parent_id": 0,
"sort": 1,
"status": 1,
"meta": {
"title": "用户列表",
"keepAlive": true
}
}
```
#### 更新权限
- **接口**: `PUT /admin/permissions/{id}`
#### 删除权限
- **接口**: `DELETE /admin/permissions/{id}`
#### 批量删除权限
- **接口**: `POST /admin/permissions/batch-delete`
#### 批量更新权限状态
- **接口**: `POST /admin/permissions/batch-status`
### 部门管理
#### 获取部门列表
- **接口**: `GET /admin/departments`
- **参数**:
- `page`, `page_size`, `keyword`, `status`, `order_by`, `order_direction`
#### 获取部门树
- **接口**: `GET /admin/departments/tree`
#### 获取所有部门(不分页)
- **接口**: `GET /admin/departments/all`
#### 获取部门详情
- **接口**: `GET /admin/departments/{id}`
#### 创建部门
- **接口**: `POST /admin/departments`
- **参数**:
```json
{
"name": "技术部",
"parent_id": 0,
"leader": "张三",
"phone": "13800138000",
"sort": 1,
"status": 1
}
```
#### 更新部门
- **接口**: `PUT /admin/departments/{id}`
#### 删除部门
- **接口**: `DELETE /admin/departments/{id}`
#### 批量删除部门
- **接口**: `POST /admin/departments/batch-delete`
#### 批量更新部门状态
- **接口**: `POST /admin/departments/batch-status`
#### 导出部门
- **接口**: `POST /admin/departments/export`
#### 导入部门
- **接口**: `POST /admin/departments/import`
- **参数**: `file` (multipart/form-data, xlsx/xls文件)
#### 下载部门导入模板
- **接口**: `GET /admin/departments/download-template`
## 权限设计
### 权限编码规则
权限编码采用 `模块.功能.操作` 的格式,例如:
- `system.user.list` - 系统管理-用户-列表
- `system.user.create` - 系统管理-用户-创建
- `system.user.update` - 系统管理-用户-更新
- `system.user.delete` - 系统管理-用户-删除
### 权限类型
- **menu**: 菜单类型,用于前端路由配置
- **api**: API接口类型用于后端权限验证
- **button**: 按钮类型,用于前端按钮权限控制
## 缓存机制
### 用户在线状态缓存
- **缓存键**: `user_online:{userId}:{tokenHash}`
- **过期时间**: 5分钟
- **用途**: 跟踪用户在线状态、最后活跃时间、登录设备信息
### 权限缓存
- **用户权限列表**: `permission:user:{userId}:permissions` (60分钟)
- **用户权限编码**: `permission:user:{userId}:permission_codes` (60分钟)
- **用户菜单树**: `permission:user:{userId}:menu_tree` (60分钟)
- **角色权限**: `permission:role:{roleId}:permissions` (60分钟)
### 缓存更新时机
- 用户登录/刷新token时更新在线状态
- 用户角色变化时,清除用户权限缓存
- 角色权限变化时,清除角色和所有关联用户的权限缓存
- 权限本身变化时,清除所有权限缓存
## 导入导出
### 用户导入模板字段
- 用户名*(必填)
- 密码*(必填)
- 真实姓名*(必填)
- 邮箱
- 手机号
- 部门名称
- 角色名称(多个用逗号分隔)
- 备注
### 部门导入模板字段
- 部门名称*(必填)
- 上级部门名称
- 负责人
- 联系电话
- 排序
- 备注
### 导出功能
- 支持导出全部数据
- 支持按选中的ID导出
- 导出文件为Excel格式
- 下载后自动删除临时文件
## 初始化数据
运行数据库迁移和填充命令:
```bash
# 执行迁移
php artisan migrate
# 填充初始数据
php artisan db:seed --class=AuthSeeder
```
初始数据包括:
- 超级管理员账号username: admin, password: 123456
- 基础角色(超级管理员、管理员)
- 完整的权限菜单
- 默认部门
## 注意事项
1. **Swoole环境注意事项**:
- 避免使用静态变量存储状态
- 避免使用全局变量
- 正确管理数据库连接
- 使用Redis缓存时注意连接池配置
2. **安全注意事项**:
- 所有密码必须加密存储
- 使用JWT进行身份认证
- 敏感操作需要记录日志
- 定期清理过期的导出文件
3. **性能优化**:
- 使用Redis缓存权限数据
- 大批量操作使用队列处理
- 分页查询避免一次性加载过多数据
4. **权限验证**:
- 在中间件中验证用户权限
- 前端根据权限控制按钮显示
- 使用权限缓存减少数据库查询
## 扩展建议
1. **日志审计**: 添加操作日志记录
2. **数据权限**: 实现基于部门的数据权限控制
3. **多租户**: 支持多租户场景
4. **SSO登录**: 支持第三方单点登录
5. **动态权限**: 支持运行时动态添加权限
## 常见问题
### Q: 如何添加新的权限模块?
A: 在Seed文件中添加新的权限数据或者通过API创建新的权限节点。
### Q: 导入大量数据时超时怎么办?
A: 使用队列处理导入任务,分批导入数据。
### Q: 如何清理权限缓存?
A: 调用 `PermissionCacheService::clearAllPermissionCache()` 方法。
### Q: Swoole环境下如何热重载
A: 运行 `php bin/laravels reload` 命令进行平滑重启。
### Q: Excel文件支持哪些格式
A: 支持.xlsx和.xls格式文件。