Back to home@Awesome-AI-Pedia

dsh-lark-web-auth

deepseek飞书登录插件,对话隔离

Stars
1
Language
TypeScript
Created
Aug 19, 2026
Updated
Aug 19, 2026
GitHub repo

Introduction

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_SECRET32+ 字节随机串,用于 cookie 签名。旋转会踢下所有用户

可选:

变量默认说明
LARK_WEB_AUTH_ENABLEDtrue设为 false 可临时禁用
LARK_WEB_DB_PATH~/.dsh/lark-web-auth.sqliteSQLite 文件路径
LARK_WEB_DOMAINfeishufeishu(国内) 或 lark(海外)

飞书开放平台设置

  1. 登录 飞书开放平台,进入自建应用(或新建一个)。
  2. 凭证与基础信息 → 记下 App ID / App Secret
  3. 添加应用能力 → 「网页」→ 主页地址填 https://web.yourdomain.com
  4. 安全设置 → 重定向 URL 填 https://web.yourdomain.com/auth/lark/callback
  5. 权限管理 → 开通 contact:user.base:readonly(拿 open_id 和昵称)。
  6. 发版申请审批 → 通过后本插件即可使用。

部署(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 / session lookup 被包一层,请求上下文里的 openId 必须等于 session_owner 表里的记录,否则抛 session-not-found
  • 列表层session.list API 返回值过滤只保留 owner 匹配的项。
  • 新对话:监听 session/created 事件,把 request context 的 openId 写入 session_ownerdm:* 前缀的 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