Files
go_blog/PERMISSIONS_AND_USER_ARTICLES.md
T
2026-06-22 19:07:13 +08:00

224 lines
7.0 KiB
Markdown
Raw 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.
# 权限控制与用户文章管理功能
## 提交摘要
本次更新修复了权限边界问题,并为普通用户添加了独立的文章管理功能。
## 1. 权限控制修复
### 问题
- 普通用户(author角色)能够访问后台管理页面 `/admin`
- 普通用户能够修改平台设置、审核评论、管理用户
- 权限边界不清晰,存在安全隐患
### 解决方案
#### 后端路由保护 ([main.go](main.go))
为所有管理功能添加 `AdminRequired` 中间件:
```go
// 整个 /admin 路径要求管理员权限
admin := router.Group("/admin")
admin.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
// 评论管理要求管理员权限
comments := router.Group("/admin/comments")
comments.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
// 用户管理要求管理员权限
users := router.Group("/admin/users")
users.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
// 平台设置要求管理员权限
settings := router.Group("/admin/settings")
settings.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
// 附件管理要求管理员权限
attachments := router.Group("/admin/articles")
attachments.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
```
#### 前端UI控制
**头部导航菜单** ([templates/layouts/base.html](templates/layouts/base.html)):
- 所有用户:个人信息、我的文章
- 仅管理员:后台管理(分隔线后显示)
**管理后台仪表板** ([templates/admin/dashboard.html](templates/admin/dashboard.html)):
- 管理员专属按钮:用户管理、评论管理、平台设置
## 2. 用户文章管理功能
### 新增功能
为普通用户创建独立的文章管理界面,无需访问后台即可管理自己的文章。
### 路由设计 ([main.go](main.go))
```go
myArticles := router.Group("/my")
myArticles.Use(middleware.AuthRequired())
{
myArticles.GET("/articles", handlers.MyArticlesPage(db))
myArticles.GET("/articles/new", handlers.MyArticleCreatePage(db))
myArticles.POST("/articles/new", handlers.MyArticleCreate(db))
myArticles.GET("/articles/:id/edit", handlers.MyArticleEditPage(db))
myArticles.POST("/articles/:id/edit", handlers.MyArticleUpdate(db))
myArticles.POST("/articles/:id/delete", handlers.MyArticleDelete(db))
}
// 用户文章附件管理
myAttachments := router.Group("/my/articles")
myAttachments.Use(middleware.AuthRequired())
{
myAttachments.POST("/attachments", handlers.UploadAttachment(db, cfg.Path))
myAttachments.POST("/attachments/:id/delete", handlers.DeleteAttachment(db, cfg.Path))
myAttachments.GET("/:id/attachments", handlers.ListAttachments(db))
}
```
### Handler实现 ([handlers/my_articles.go](handlers/my_articles.go))
**权限控制特点**
- `MyArticlesPage`: 只查询当前用户的文章 (`WHERE author_id = ?`)
- `MyArticleEditPage`: 验证文章所有权 (`WHERE id = ? AND author_id = ?`)
- `MyArticleUpdate`: 验证文章所有权后才允许更新
- `MyArticleDelete`: 验证文章所有权后才允许删除
### 模板文件
**文章列表** ([templates/user/my_articles.html](templates/user/my_articles.html)):
- 显示用户自己的文章
- 支持创建、编辑、删除操作
- 显示文章状态(草稿/已发布/置顶)
**文章编辑器** ([templates/user/my_article_form.html](templates/user/my_article_form.html)):
- Markdown编辑器支持
- 标题、slug、摘要、正文、封面
- 状态选择(草稿/发布)
- 置顶选项
### 国际化支持 ([i18n/i18n.go](i18n/i18n.go))
新增翻译key
```go
// 英文
"my_articles": "My Articles",
"my_articles_title": "My Articles",
"comment_manage": "Manage Comments",
"article_field_*": // 表单字段标签
"article_save": "Save",
"article_cancel": "Cancel",
// 中文
"my_articles": "我的文章",
"my_articles_title": "我的文章",
"comment_manage": "评论管理",
// ...
```
## 3. 权限矩阵
| 功能 | 路径 | admin | author | 未登录 |
|------|------|-------|--------|--------|
| 管理后台 | `/admin` | ✓ | ✗ | ✗ |
| 文章管理(后台) | `/admin/articles` | ✓ | ✗ | ✗ |
| 评论管理 | `/admin/comments` | ✓ | ✗ | ✗ |
| 用户管理 | `/admin/users` | ✓ | ✗ | ✗ |
| 平台设置 | `/admin/settings` | ✓ | ✗ | ✗ |
| **我的文章** | `/my/articles` | ✓ | ✓ | ✗ |
| 个人资料 | `/profile` | ✓ | ✓ | ✗ |
| 文章浏览 | `/article/:slug` | ✓ | ✓ | ✓ |
## 4. 用户体验
### 普通用户(author
1. 登录后点击头像
2. 看到选项:
- 个人信息
- **我的文章** ← 新增
- 退出登录
3. 点击"我的文章"进入独立的文章管理界面
4. 可以创建、编辑、删除自己的文章
5. 无法访问后台管理功能
### 管理员(admin
1. 登录后点击头像
2. 看到选项:
- 个人信息
- 我的文章
- ---(分隔线)---
- **后台管理** ← 管理员专属
- 退出登录
3. 点击"后台管理"进入完整的管理后台
4. 后台仪表板显示管理员专属按钮:
- 用户管理
- 评论管理
- 平台设置
## 5. 安全改进
### 多层防护
1. **路由层**`AdminRequired` 中间件拦截未授权访问
2. **Handler层**:查询时验证用户身份和所有权
3. **UI层**:根据角色隐藏不该显示的按钮和链接
### 拦截行为
- 普通用户访问 `/admin/*` → 重定向到 `/admin`
- 由于 `/admin` 也需要管理员权限 → 再次重定向到 `/admin`
- 实际效果:普通用户无法访问任何管理功能
## 6. 测试建议
### 管理员账户测试
```bash
# 登录管理员
访问 http://localhost:8080/login
用户名: admin
密码: (你的管理员密码)
# 应该能访问:
- /admin (后台仪表板)
- /admin/articles (文章管理)
- /admin/comments (评论管理)
- /admin/users (用户管理)
- /admin/settings/site (平台设置)
- /my/articles (我的文章)
```
### 普通用户测试
```bash
# 创建或登录普通用户
访问 http://localhost:8080/login
用户名: author
密码: (普通用户密码)
# 应该能访问:
- /my/articles (我的文章)
- /profile (个人资料)
# 不应该能访问(会被拦截):
- /admin
- /admin/comments
- /admin/users
- /admin/settings
```
## 7. 文件变更清单
### 新增文件
- `handlers/my_articles.go` - 用户文章管理handler
- `templates/user/my_articles.html` - 文章列表模板
- `templates/user/my_article_form.html` - 文章编辑表单
- `test_permissions.md` - 权限测试文档
### 修改文件
- `main.go` - 添加权限中间件和用户文章路由
- `i18n/i18n.go` - 添加翻译key
- `templates/layouts/base.html` - 简化导航菜单
- `templates/admin/dashboard.html` - 添加管理员专属按钮
## 8. 后续改进建议
1. **细粒度权限**:考虑添加编辑角色,可以编辑所有文章但不能管理用户
2. **文章协作**:允许管理员指定文章的协作者
3. **审计日志**:记录敏感操作(用户管理、设置修改)
4. **草稿分享**:生成草稿预览链接,方便审稿
5. **文章统计**:在"我的文章"页面显示阅读量、评论数等统计数据