READMESource: master@41e8c7b2
dsh-lark-web-auth
DeepSeek Harness × 飞书登录 · 多用户 Web GUI 隔离
给 DeepSeek Harness Web GUI 加上飞书 OAuth 登录,让企业内部员工从公网访问,每人只能看到自己的对话。与 dsh-lark-link 完美配合:飞书 bot 里聊过的对话,登录网页后自动看到。
它做什么
- 飞书 OAuth 登录 — 未登录用户访问网页时自动跳转飞书授权,回调后写 httpOnly cookie。
- Session 隔离 — 每个
session_id归属一个open_id;用户只能看到、访问、修改自己的 session。非 owner 请求统一返回 404,不泄露存在性。 - 存量数据自动归属 — 首次启动时扫描
dm:*前缀的 session(dsh-lark-link创建的),通过飞书 API 反查chat_id → open_id,写入归属表。 - 登录态持久化 — SQLite 存储,进程重启不掉线。
- 零前端源码修改 — 通过
webServer.tapIndex()注入小 UI(登录跳转 + 右上角用户菜单),不动 harness 前端源码。
安装
dsh plugin --profile web add dsh-lark-web-auth
配置
必需环境变量:
| 变量 | 说明 |
|---|---|
LARK_WEB_APP_ID |
飞书自建应用 App ID(可复用 dsh-lark-link 的) |
LARK_WEB_APP_SECRET |
飞书自建应用 App Secret |
LARK_WEB_BASE_URL |
公网访问的 URL,如 https://web.yourdomain.com |
LARK_WEB_COOKIE_SECRET |
32+ 字节随机串,用于 cookie 签名。旋转会踢下所有用户 |
可选:
| 变量 | 默认 | 说明 |
|---|---|---|
LARK_WEB_AUTH_ENABLED |
true |
设为 false 可临时禁用 |
LARK_WEB_DB_PATH |
~/.dsh/lark-web-auth.sqlite |
SQLite 文件路径 |
LARK_WEB_DOMAIN |
feishu |
feishu(国内) 或 lark(海外) |
飞书开放平台设置
- 登录 飞书开放平台,进入自建应用(或新建一个)。
- 凭证与基础信息 → 记下
App ID/App Secret。 - 添加应用能力 → 「网页」→ 主页地址填
https://web.yourdomain.com。 - 安全设置 → 重定向 URL 填
https://web.yourdomain.com/auth/lark/callback。 - 权限管理 → 开通
contact:user.base:readonly(拿 open_id 和昵称)。 - 发版申请审批 → 通过后本插件即可使用。
部署(Caddy 示例)
web.yourdomain.com {
reverse_proxy localhost:3080
}
启动:
export LARK_WEB_APP_ID=cli_xxxxx
export LARK_WEB_APP_SECRET=xxxxx
export LARK_WEB_BASE_URL=https://web.yourdomain.com
export LARK_WEB_COOKIE_SECRET=$(openssl rand -base64 32)
dsh --profile web
加载顺序
此插件必须在 api-remotes 之后加载——它用 ctx.inject(['typert']) 覆盖 typert lookup,晚注册者生效。cordis.patch.yml 里默认已经用 insert: 尾部追加。
与 dsh-lark-link 的关系
- 无依赖,可以独立用(仅 web 端登录,不与飞书 bot 交互)。
- 一起用时:
dsh-lark-link把飞书 P2P chat 变成一个 harness session(key =dm:${chat_id}),本插件把该 session 归属到用户 open_id,登录后网页可见。
数据隔离怎么保证
- HTTP 层:所有
/api/*请求先过 middleware 校验 cookie,未登录返 401。 - RPC 层:typert 的
agent/sessionlookup 被包一层,请求上下文里的openId必须等于session_owner表里的记录,否则抛session-not-found。 - 列表层:
session.listAPI 返回值过滤只保留 owner 匹配的项。 - 新对话:监听
session/created事件,把 request context 的openId写入session_owner;dm:*前缀的 lark-link 会话按 chat_id 反查 open_id。
Known Limitations
- 单机 SQLite 存储,不支持多实例部署(100 人以内足够)。
- 存量数据回填是尽力而为——如果飞书 API 反查
chat_id → open_id失败(如飞书返回 403),那条 session 保留无 owner 状态,任何人都看不到,需要手动分配(未来加 CLI)。 - 不支持团队/群组 session 共享,一个 session 只能属于一个人。
- 未做审计日志(谁看了谁的 session);100 人规模够用,更大规模需要增强。
License
MIT
No comments yet. Be the first to write one.