Mix Space v10 对鉴权体系进行了全面重构,从传统 JWT 迁移到基于 Better Auth 的现代化会话管理。本指南将帮助你顺利完成升级。
v10 带来了更安全、更灵活的身份验证体系:
- Cookie Session 替代 JWT,提供更好的安全性和自动刷新能力
- 多登录方式 统一管理(密码、OAuth、Passkey)
- 独立的 API Key 系统,支持更细粒度的权限控制
- Reader 角色体系,为未来的多用户功能奠定基础
启动新版本时会自动执行数据迁移,无需手动干预。迁移过程是幂等的,可以安全地多次运行。
升级前务必备份 MongoDB 数据:
mongodump --uri="$MONGO_URI" --out=./backup-$(date +%Y%m%d)| 组件 | 最低版本 |
|---|---|
| Node.js | 22+ |
| MongoDB | 5.0+ |
| admin-vue3 | v10 配套版本 |
- 确保 MongoDB 和 Redis 正常运行
- 如果使用 OAuth,确认第三方服务配置正确
启动时会自动执行以下迁移:
| 迁移版本 | 说明 |
|---|---|
| v9.7.0 | 创建 Better Auth 基础数据结构,迁移 API Key 和 Passkey |
| v9.7.1 | 同步 username 到新账户系统 |
| v9.7.2 | 清理旧 users.apiToken 字段 |
| v9.7.3 | 迁移 role 字段(isOwner → role: "owner") |
| v9.7.4 | 迁移 owner 资料和密码凭证到新表结构 |
| v9.7.5 | 添加 owner 唯一性约束 |
| v9.7.6 | 删除旧 users 集合 |
检查以下关键点:
# 连接 MongoDB 验证数据
mongosh "$MONGO_URI"// 确认 owner 账户存在且唯一
db.readers.find({ role: "owner" }).count() // 应该是 1
// 确认 API Key 已迁移
db.apikey.find().count() // 应该大于 0(如果之前有配置)- 使用密码 / OAuth / Passkey 登录管理后台
- 调用 API 时使用
x-api-key头验证
| 变更项 | v9 (旧) | v10 (新) |
|---|---|---|
| 用户身份 |
|
|
| API Key |
|
|
| Owner 判断 | users.isOwner: true |
readers.role: "owner"(唯一约束) |
| 场景 | v9 (旧) | v10 (新) |
|---|---|---|
| API Key 传递 | Authorization: Bearer <token> |
x-api-key: <token> |
| 管理端登录 | JWT Token | Cookie Session |
| 会话持久化 | 客户端存储 JWT | 服务端 Session + Cookie |
⚠️ Authorization: Bearer <txo...>仍可用但已标记为 deprecated,建议尽快迁移到x-api-key。
| 功能 | v9 (旧) | v10 (新) |
|---|---|---|
| 登录 | POST /master/login |
Better Auth signIn.username |
| 登出 | POST /user/logout |
Better Auth signOut |
| 获取 owner 信息 | GET /master |
GET /owner |
| 更新 owner 信息 | PATCH /master |
PATCH /owner |
| 检查登录状态 | GET /master/check_logged |
GET /owner/check_logged |
| 查询登录方式 | GET /user/allow-login |
GET /owner/allow-login |
| 会话列表 | GET /user/session/all |
Better Auth listSessions |
| 撤销会话 | DELETE /user/session/:id |
Better Auth revokeSession |
| 初始化注册 | POST /user/register |
POST /init/owner |
| Owner 评论回复 | POST /comments/master/reply/:id |
POST /comments/owner/reply/:id |
v10 移除了 TextMacroService,不再支持文本中的宏语法([[ $variable ]]、[[ #function() ]])。
影响范围:
- Post / Note / Page 的 WebSocket 广播与 API 响应中不再进行宏替换,文本将以原始内容返回
- Markdown 渲染接口 (
renderArticle) 不再预处理宏
前端适配:如果前端依赖宏替换后的文本(如 [[ #dayjs().format('YYYY') ]] 渲染为年份),需自行在前端实现相应逻辑,或移除文本中的宏语法。
配置:textOptions 配置节已从 schema 中移除,升级后该配置将被忽略。
| 方法 | v9 (旧) | v10 (新) |
|---|---|---|
| 获取 owner 信息 | context.getMaster() |
context.getOwner() |
现象:使用旧密码无法登录
排查:
// 检查密码是否已迁移
db.account.findOne({ providerId: "credential" })
// 应该有 password 字段解决:如果密码未迁移,可能是旧 users 集合中没有密码字段。可以通过 OAuth 或 Passkey 登录后重置密码。
现象:使用 Authorization: Bearer <token> 返回 401
排查:
// 检查 API Key 是否已迁移
db.apikey.find({ key: /^txo/ })解决:
- 确认使用
x-api-key头而非Authorization - 检查 key 的
enabled字段是否为true - 检查
expiresAt是否已过期
现象:启动后数据结构未变化
排查:查看启动日志中是否有迁移相关输出
解决:迁移状态记录在 migrations 集合中,可以删除对应记录后重新启动:
db.migrations.deleteOne({ version: "v9.7.0-better-auth-migration" })如果需要回滚到 v9:
- 停止 v10 服务
- 恢复数据库备份
mongorestore --uri="$MONGO_URI" --drop ./backup-YYYYMMDD - 切换到 v9 代码并启动
⚠️ v10 的迁移脚本会删除旧users集合,回滚前必须先恢复数据库。
A: 取决于数据量,通常几秒到几分钟。迁移是一次性的,后续启动不会重复执行。
A: 是的,所有在 users.apiToken 数组中的 Key 都会迁移到 apikey 集合。
A: 可以。Passkey 会自动迁移到新的 passkey 集合,OAuth 配置保持不变。
A: Cookie Session 提供了更好的安全性(HttpOnly、自动过期)、更简单的实现(无需客户端管理 Token)、以及更好的跨标签页同步。