Echo Server:帖子系统从 0 到 1
社区项目CRUD鉴权
0. 为什么必须补这一页
评论、点赞和统计聚合都依赖帖子系统。如果只写创建 posts 表就跳到评论点赞,读者会不知道 post_id 从哪里来,也不知道删除权限如何判断。
| 项目 | 说明 |
|---|---|
| 建议位置 | 精选作品详情页 / 项目文档页 |
| 统一风格 | 左侧导航、右侧正文、表格说明、折叠代码块、阶段总结。 |
| 阅读顺序 | 建议从总览页进入,再按卡片顺序阅读。 |
1. posts 表设计
posts 表保存发帖人、正文、图片、创建时间,并通过外键关联 users。
CREATE TABLE IF NOT EXISTS posts (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
content TEXT NOT NULL,
image_url VARCHAR(255) DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_posts_user_id (user_id),
INDEX idx_posts_created_at (created_at),
INDEX idx_posts_id (id),
CONSTRAINT fk_posts_user_id
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;2. token 鉴权辅助函数
发帖和删帖不能相信客户端传来的 user_id,必须从 Authorization 请求头里的 demo_token 解析当前用户。
long long getUserIdFromRequest(const HttpRequestPtr& req) {
std::string auth = req->getHeader("Authorization");
std::string prefix = "Bearer demo_token_";
if (auth.rfind(prefix, 0) != 0) {
return -1;
}
std::string idStr = auth.substr(prefix.size());
try {
return std::stoll(idStr);
} catch (...) {
return -1;
}
}3. 接口设计
建议统一使用 /api/posts 前缀,并保持复数形式。
POST /api/posts/create
请求头:Authorization: Bearer demo_token_用户ID
请求体:{"content":"第一条帖子","image_url":""}
GET /api/posts/latest?page=1&page_size=20
返回:最新帖子列表
GET /api/posts/user?user_id=1&page=1&page_size=20
返回:指定用户主页帖子列表
GET /api/posts/detail?post_id=1
返回:帖子详情
POST /api/posts/delete
请求头:Authorization: Bearer demo_token_用户ID
请求体:{"post_id":1}4. 联调测试命令
按登录、发帖、查最新、查用户主页、查详情、删帖的顺序测试。
TOKEN="demo_token_1"
curl -s -X POST http://127.0.0.1:8080/api/posts/create -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -d '{"content":"这是第一条帖子","image_url":""}' | jq
curl -s "http://127.0.0.1:8080/api/posts/latest?page=1&page_size=20" | jq
curl -s "http://127.0.0.1:8080/api/posts/user?user_id=1&page=1&page_size=20" | jq
curl -s "http://127.0.0.1:8080/api/posts/detail?post_id=1" | jq
curl -s -X POST http://127.0.0.1:8080/api/posts/delete -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -d '{"post_id":1}' | jq