Skip to content

feat(auth): 支持自托管访问鉴权与笔记同步#378

Open
techotaku39 wants to merge 5 commits into
JefferyHcool:developfrom
techotaku39:feature/auth-self-host-sync
Open

feat(auth): 支持自托管访问鉴权与笔记同步#378
techotaku39 wants to merge 5 commits into
JefferyHcool:developfrom
techotaku39:feature/auth-self-host-sync

Conversation

@techotaku39
Copy link
Copy Markdown

@techotaku39 techotaku39 commented May 25, 2026

改动概述

为开源自托管部署补齐可选访问鉴权和后端笔记历史同步能力。

开启鉴权后,Web 前端和浏览器插件都需要使用同一个自托管访问密码登录,才能访问受保护的后端接口;同时 Web 前端和插件会从后端同步已生成笔记历史,让不同设备访问同一个自托管服务时能看到一致的笔记列表。

这个 PR 面向的是个人 / 单用户自托管场景:解决公网部署没有访问保护、以及后端已有笔记但不同设备历史不同步的问题。它不引入注册、账号管理、团队空间或多用户数据隔离,也不改变 BiliNote Pro 的多用户产品定位。

为什么

原项目在自托管场景下有两个比较明显的问题:

  1. 公网部署缺少访问保护
    BiliNote 自托管服务默认没有鉴权。如果直接部署到服务器并暴露访问地址,任何知道地址的人都可以打开 Web 页面、调用后端接口、消耗模型额度或查看生成内容。
    反代层加 Basic Auth / Cloudflare Access 虽然能保护页面,但浏览器插件需要直接请求后端 API,现有插件并不会自动携带这些外部鉴权信息,因此容易出现 Web 能保护、插件不可用或 API 仍裸露的问题。

  2. 笔记内容在后端,但历史列表主要依赖本地状态
    后端会把生成结果写入 backend/note_results,但 Web 前端历史和插件任务记录主要依赖浏览器本地状态。
    结果是:同一个自托管服务中,设备 A 生成的笔记已经存在后端,设备 B 打开同一个服务时却看不到这篇笔记历史,需要重新生成或手动找任务。

因此这个 PR 选择做一个相对克制的开源自托管方案:

  • 不做完整多用户系统;
  • 不迁移现有数据模型到 user / workspace;
  • 不处理注册、邀请、团队协作等 Pro 形态能力;
  • 只提供一个可选的单用户访问密码,并让 Web / 插件都能使用这套鉴权;
  • 同时把后端已有的笔记结果作为同步来源,让同一自托管实例下的多设备历史保持一致。

这样可以解决自托管用户最直接的安全和同步问题,又尽量减少对现有架构、默认本地使用流程和 Pro 产品边界的影响。

做了什么

后端:可选单用户鉴权

  • 新增环境变量控制鉴权:
    • BILINOTE_AUTH_ENABLED
    • BILINOTE_AUTH_PASSWORD
    • BILINOTE_AUTH_TOKEN_EXPIRE_DAYS
  • 新增鉴权接口:
    • GET /api/auth/status
    • POST /api/auth/login
    • POST /api/auth/logout
  • 新增鉴权中间件:
    • 鉴权开启后保护 /api/*/static/*/uploads/*
    • 健康检查接口保持未登录可访问,避免 Docker / 前端启动检查被鉴权拦截
  • 默认关闭鉴权,保持本地开发和原有部署方式兼容。

后端:笔记历史同步来源

  • 新增 backend/app/services/note_storage.py,从后端 note_results 读取可同步的笔记历史。
  • 任务完成后写入可同步的笔记元数据。
  • 新增笔记列表读取和删除相关能力。
  • 过滤 _markdown / _audio / _request / _transcript 等缓存产物任务,避免同步历史里出现删不掉的伪等待任务。

Web 前端:登录与历史同步

  • 新增 AuthGate,在后端开启鉴权时显示访问密码登录。
  • 请求层自动携带 token。
  • 历史列表支持从后端同步笔记。
  • 同步历史时过滤缓存产物任务。
  • 当前任务不存在时自动切换到有效任务,避免选中已删除或无效任务后卡住。

浏览器插件:自托管后端鉴权与同步

  • 插件设置页支持配置后端地址、连通性状态和鉴权状态。
  • 插件可输入访问密码登录自托管后端,并在后续请求中携带 token。
  • Popup / Sidepanel 可从服务端同步笔记历史。
  • 兼容后端地址简写:
    • 3015
    • localhost:3015
    • http://host:3015/api
    • 等格式会归一化为可用后端地址。
  • 区分“后端连通”和“鉴权状态”,避免把服务不可达和未登录混为同一个错误。

文档与配置

  • 更新 .env.example
  • 更新 backend/.env.example
  • 更新 README 自托管鉴权和笔记同步说明
  • 更新 Dockerfile 相关配置

相比原项目的改进

  • 自托管服务可以通过内置访问密码保护,不再必须依赖外部反代鉴权。
  • Web 前端和浏览器插件使用同一套自托管鉴权,避免“Web 被保护但插件不可用”的割裂体验。
  • 后端已有笔记结果可以同步到 Web / 插件历史列表,不同设备访问同一服务时能看到一致历史。
  • 删除 / 同步历史时会过滤缓存产物任务,减少 _markdown_audio 等伪任务出现在历史列表的问题。
  • 默认关闭鉴权,不影响原本本地使用、开发和未启用鉴权的自托管部署。

测试方式

  • pnpm build(Web 前端)通过
  • pnpm build(浏览器插件)通过
  • pnpm typecheck(浏览器插件)通过(先运行 build 生成插件项目 gitignored 的 auto-import 类型文件)
  • python -m py_compile backend/app/services/auth.py backend/app/services/note_storage.py backend/app/routers/auth.py backend/app/middlewares/auth.py backend/main.py 通过
  • 手动验证步骤:
    • 本地 Docker 集成环境启用自托管鉴权后,可使用配置密码登录 Web 端
    • 未登录访问受保护 API 会被拦截,健康检查仍可访问
    • 浏览器插件配置 3015 后可解析为 http://localhost:3015 并连通后端
    • 插件可区分后端连通状态和鉴权登录状态
    • Web 端与插件可从同一后端同步已生成笔记历史
    • /api/notes 不再返回 _markdown / _audio / _request / _transcript 缓存产物伪任务

回归风险

  • 影响后端请求链路、Web 前端请求层和浏览器插件设置 / 同步逻辑,建议重点回归:
    • 未启用鉴权的默认本地使用流程
    • Docker 自托管启用鉴权后的登录流程
    • 插件连接自托管服务、登录鉴权、生成笔记、同步历史流程
    • Web 端历史同步与删除后不再出现伪等待任务
  • 需要后端与前端 / 插件同步部署;仅升级前端或仅升级后端时,同步 / 鉴权能力可能不可用。
  • 这是单用户自托管访问保护,不提供多用户数据隔离;如果多个用户共用同一个密码,仍然会看到同一份后端历史。

Checklist

  • 分支命名遵循 CONTRIBUTING.md §3feature/auth-self-host-sync
  • base 分支正确(常规功能 → develop
  • Commit message 遵循 type(scope): subject 格式
  • 已自测核心流程
  • 已更新相关文档(README.md / env example)
  • 未夹带 secrets / .env / 大型二进制
  • 单 PR 不跨多个工作区做无关改动

@techotaku39 techotaku39 changed the title feat(auth): 新增自托管鉴权与笔记同步 feat(auth): 支持自托管访问鉴权与笔记同步 May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants