Karakeep 自托管用户管理实战:密码重置、管理员授权与禁用注册后的用户创建
【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder
本指南聚焦 Karakeep(原 Hoarder)自托管部署中的用户管理三大高频问题:忘记密码时如何恢复、如何将普通用户提升为管理员,以及在关闭公开注册后如何继续创建新账号。文章以 v0.30.0 版本的官方 FAQ 为骨架,结合仓库内packages/trpc的路由与模型实现,带你既会"照着操作",也明白每一步背后的存储与鉴权原理。
背景:Karakeep 的用户角色与密码存储模型
在进入具体操作前,先理解 Karakeep 的用户体系,这能帮助你判断该走哪条恢复路径:
- 用户表
user中通过role字段区分admin与user两种角色,role为空的用户按普通用户对待,相关定义见 schema.ts; - 密码并非明文存储,而是通过 bcrypt 加盐哈希后写入
password字段,盐值保存在独立的salt字段中,哈希逻辑见 auth.ts; - 注册/重置时调用的校验函数
validatePassword会执行bcrypt.compare(password + salt, user.password),也就是说最终校验的是"密码 + 盐"拼接后的哈希结果,见 auth.ts。
理解这一点后就不难明白:官方 FAQ 提供的那条 SQL 之所以把salt清空,就是为了让"明文密码 + 空盐"能够匹配上预设的 bcrypt 哈希。
忘记密码:普通用户的恢复路径
如果你不是管理员,Karakeep 的恢复流程是"找管理员帮你重置",而不是自行处理:
- 登录任意管理员账号,进入
Admin Settings(管理设置)页面; - 在
Users List(用户列表)中找到目标用户; - 在
Actions(操作)列中点击重置密码按钮; - 输入新密码并点击
Reset(重置); - 新密码即刻生效,用户可以立即登录;
- 出于隐私考虑,登录后可在
User Settings(用户设置)中再次修改密码,这样管理员也并不知道你最终使用的密码。
这条路径背后的接口是管理端 tRPC 路由adminAppRouter.resetPassword,其实现位于 routers/admin.ts。值得注意的源码细节是:管理员不能重置自己的密码——如果ctx.user.id == input.userId,接口会直接抛出BAD_REQUEST("Cannot reset own password"),这正是为什么"管理员忘记密码"必须走下面的数据库方案。此外,重置时会调用generatePasswordSalt()生成新的 32 字节随机盐,并用hashPassword(input.newPassword, newSalt)重新哈希后写入数据库,整个过程是服务端标准的安全实践。
忘记密码:管理员直接改数据库的完整步骤
如果你自己就是唯一的管理员,且已经无法登录,就只能绕过应用层,直接修改 SQLite 数据库。Karakeep 的数据库文件为db.db,存放在数据目录中;在 Docker 部署下,该目录对应容器内挂载的/data,见 docker-compose.yml 中的data:/data卷映射(DATA_DIR环境变量即指向此目录,说明见 环境变量文档)。
完整操作流程如下:
准备数据库工具
- Linux 下可用
sqlite3,例如 Debian/Ubuntu 系执行apt-get install sqlite3(具体命令取决于你的包管理器); - Windows 下可使用图形化工具,例如
dbeaver。
- Linux 下可用
停止 Karakeep 服务必须先在数据目录中停掉应用,避免运行中的进程在修改期间向数据库写入数据。
连接数据库在数据目录中执行
sqlite3 db.db,或用dbeaver通过 UI 定位到 data 目录下的db.db文件并连接。执行密码更新 SQL运行以下语句(务必把
<YOUR_EMAIL_HERE>替换成你自己的邮箱):update user set password='$2a$10$5u40XUq/cD/TmLdCOyZ82ePENE6hpkbodJhsp7.e/BgZssUO5DDTa', salt='' where email='<YOUR_EMAIL_HERE>';这条语句做了两件事:将
password字段替换为预生成的 bcrypt 哈希,同时把salt置为空字符串。根据 auth.ts 的哈希规则,该哈希对应的明文密码为adminadmin。重启 Karakeep,用你的邮箱和密码
adminadmin登录。登录成功后立即改密:进入
User Settings,把密码修改为任意你想要的强密码,完成整个恢复流程。
原理说明:为什么这条 SQL 能生效
从源码看,密码校验链路是bcrypt.compare(password + (user.salt ?? ""), user.password)(auth.ts)。SQL 将salt置空后,校验等式退化为bcrypt.compare('adminadmin', '$2a$10$5u40XUq/...'),而该哈希正是adminadmin在成本因子 10 下的 bcrypt 结果(BCRYPT_SALT_ROUNDS = 10,见 auth.ts),因此登录成功。这也解释了为什么不能只改password而不动salt——盐不匹配时同样的哈希无法通过校验。
添加另一位管理员
Karakeep 的管理员机制有一个默认行为:第一个注册的用户会自动被提升为管理员。这一逻辑可以在用户模型的createRaw方法中找到依据:创建用户时若表中用户数为 0,则角色被设置为admin,见 models/users.ts。
如果你想授予其他用户管理员权限:
- 以管理员身份进入
Admin Settings页面; - 在
Users List中找到目标用户; - 在
Actions列点击修改角色(Role)的按钮; - 将角色改为
Admin并点击Change(更改); - 该用户需要退出登录并重新登录,新的角色才会生效。
角色变更由管理路由adminAppRouter.updateUser完成,源码位于 routers/admin.ts。该接口同样禁止修改自己的角色("Cannot update own user"),并且支持在同一个接口里调整用户的bookmarkQuota、storageQuota、browserCrawlingEnabled等配额与权限字段,管理员面板的角色按钮只是其中一种用法。
禁用公开注册后,如何添加新用户
很多自托管部署会在配置中关闭公开注册,仅保留内部成员使用。此时普通用户无法自行注册,但管理员随时可以通过后台创建账号:
- 进入
Admin Settings页面; - 切换到
Users List; - 点击
Create User(创建用户)按钮; - 填写用户信息(姓名、邮箱、初始密码等);
- 点击
create(创建); - 新用户即可使用该凭据登录。
对应的后台接口是adminAppRouter.createUser,见 routers/admin.ts,它最终调用User.create完成落库(models/users.ts)。源码层面有两点值得注意:
- 若部署时开启了邮箱验证(
auth.emailVerificationRequired配置项),创建用户时会顺带生成验证令牌并发送验证邮件,新用户在完成邮箱验证前登录能力会受限; - 创建时邮箱字段具有唯一约束,若邮箱已被占用,底层会抛出
SQLITE_CONSTRAINT_UNIQUE并被转换为 "Email is already taken" 的友好错误(models/users.ts),因此你无法通过该入口为已存在用户创建重复账号。
安全注意事项与最佳实践
结合官方 FAQ 与源码实现,以下是几个容易被忽略的关键点:
- 数据库直改密码后必须立刻改密:
adminadmin是公开文档中公开的默认值,任何能接触数据库或日志的人都可能尝试用它登录,恢复成功后第一步永远是去User Settings修改密码; - 修改数据库前务必停服:SQLite 在同一进程写入时若被外部工具并发修改,可能造成锁冲突或数据损坏;且应用内存中可能缓存了旧的用户状态;
- 不要重置自己的密码:应用层接口(管理员重置、角色变更)均禁止操作自身账号,这是刻意的安全设计,防止管理员误操作锁死唯一管理员,也提醒你提前为团队配置至少两个管理员账号;
- 角色变更需要重新登录:权限在会话建立时即已确定,提升角色后让对方重新登录,才能确保新权限在 Web 端、移动端与 API 会话中一致生效;
- 若开启了 OAuth 登录,部分账号可能没有本地密码(
password字段为空),这类账号在 validatePassword 中会直接拒绝密码登录,应走正常的 OAuth 流程,而非数据库改密。
总结
Karakeep 的用户管理在设计上区分了"应用层操作"与"数据库兜底"两级恢复手段:普通用户密码丢失由管理员在后台一键重置;唯一管理员密码丢失则通过 sqlite 直改user表完成。同时,角色提升与账号创建都集中在Admin Settings中,配合"首用户自动成为管理员"的默认策略,单管理员自托管也能顺畅地把权限与账号管理交接出去。理解了 bcrypt 加盐哈希与user表字段结构,你就能在遇到类似问题时举一反三,安全地完成各类恢复操作。
【免费下载链接】hoarderA self-hostable bookmark-everything app (links, notes and images) with AI-based automatic tagging and full text search项目地址: https://gitcode.com/GitHub_Trending/ho/hoarder
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考