Hister 多用户模式完全指南:认证、用户管理、权限隔离与公共访问 📅 发布时间:2026/9/20 3:18:41 👁 浏览次数: 搜索引擎全文检索后端前端CLI【免费下载链接】histerYour own search engine项目地址https://gitcode.com/GitHub_Trending/hi/hister点击查看免费下载本指南基于 Hister 仓库中的官方文档 user-handling.md 编写并结合仓库源码config/config.go、server/model/user.go、cmd/users.go、server/session.go、server/server.go 等对每一个配置项、命令与安全机制进行源码级印证与深入展开。读完本文你将能够在一台 Hister 实例上启用多用户隔离为团队成员创建账号、配置 OAuth 单点登录、管理个人访问令牌并理解文档所有权与搜索作用域在底层是如何实现的。一、功能总览多用户如何共享同一实例Hister 的多用户处理User Handling允许多个相互独立的用户共享单个 Hister 实例。开启后每个用户拥有独立的登录凭据用户名 密码或 OAuth 身份独立的文档集合与按作用域过滤的搜索结果独立的个人访问令牌Personal Access Token供 API 客户端与 CLI 使用独立的规则Skip / Priority / Versioning与搜索别名Aliases。底层实现上服务器共享同一套索引文件但在搜索时强制执行文档所有权ownership。用户 ID 被写入每个文档索引记录查询时按用户 ID 过滤详见下文「文档隔离」一节。关键的设计取向是默认关闭app: user_handling: false # 默认值即单用户模式由于用户处理默认关闭Hister 保持完全向后兼容——现有单用户部署无需任何改动。已索引的文档存储在用户 ID0之下在开启用户处理之后依然对所有已认证用户可见见「单用户兼容」一节。在 config/config.go 中app段的结构体字段与 YAML 键一一对应UserHandling bool \yaml:user_handling与AccessToken、Public 等同级。二、激活多用户模式在配置文件的app段设置app: user_handling: true注意当user_handling生效时app.access_token的含义发生变化——它不再作为全局客户端令牌而仅用于将请求认证为对应 token 的用户。典型用法是Hister 管理员在配置文件中把app.access_token设为自己的个人访问令牌从而用命令行 Hister 命令以管理员身份执行操作见 server/server.go 的populateUserContext请求头携带的X-Access-Token会先尝试按用户 token 解析。开启后先重启服务器并至少创建一个用户账号然后才能登录。创建用户的方法见下文「用户管理命令」。三、认证机制3.1 Web 界面登录与会话启用用户处理后Web 界面会向未登录访客展示登录页输入用户名与密码即可登录。会话的底层机制在 server/session.go 中实现要点如下Cookie 内容仅包含一个随机的、不透明的会话标识符32 字节随机数Base64 编码不包含任何用户数据会话数据与标识符的哈希存储在 SQL 数据库中。过期策略会话在最近一次有效请求后30 天过期sessionMaxAge见 server/session.go每次有效请求都会刷新会话与 Cookie 的过期时间重新计算为距该请求 30 天。Cookie 属性HttpOnlytrue、SameSiteLaxSecure属性由server.base_url决定——当 base URL 使用 HTTPS 时启用使用 HTTP 时禁用因此本机回环loopbackHTTP 实例仍可正常登录。令牌存储数据库只保存会话令牌的SHA-256 哈希sessionTokenHash见 server/session.go数据库泄露不会直接暴露可用会话。明文 HTTP 无法保护会话免受网络窃听因此任何暴露到网络的实例都应使用 HTTPS。对Secure属性的判定可在 server/session.go 中看到Secure: parsedBaseURL ! nil parsedBaseURL.Scheme https。如果配置了 OAuth 提供方登录页还会显示Sign in with Provider按钮见下文 OAuth 登录。3.2 OAuth 登录当server.oauth配置了 GitHub、Google 或任意 OpenID ConnectOIDC提供方时用户可以通过 OAuth 登录OAuth 账号无需密码。第一次通过 OAuth 登录时Hister 会自动创建与之绑定的本地账号用户名的来源因提供方而异见 server/oauth 目录提供方用户名来源回退方案源码GitHub登录名login—github.goGoogle账号名称name完整邮箱地址google.goOIDCpreferred_username完整邮箱地址oidc.go此后使用同一提供方身份登录会复用同一账号通过OAuthID字段匹配见 server/model/user.go 的GetUserByOAuthID/CreateOAuthUser。OAuth 账号与密码账号功能完全一致拥有作用域内的文档与搜索结果、个人访问令牌、规则和别名。OAuth 用户可以在个人资料页Profile生成个人访问令牌用于 CLI 或浏览器扩展。配置方法见 configuration.md 的 OAuth 章节。配置校验逻辑在 config/config.go 的validateOAuth中合法提供方名称为github、google、oidcclient_id与client_secret必填OIDC 还需提供configuration_url或auth_url。3.3 OAuth-Only 模式设置server.oauth_only: true可彻底禁用密码登录Web 界面只接受 OAuth 登录登录页隐藏凭据表单只显示 OAuth 提供方按钮。这适用于强制单点登录SSO策略、防止用户用本地设置的密码绕过 SSO 的场景。在oauth_only模式下个人访问令牌依然有效因此 API 客户端和 CLI 工具无需浏览器登录即可完成认证。在多用户模式下app.access_token作为客户端默认令牌必须包含某个用户的个人令牌才能认证成功。完整配置参考见 configuration.md 的 OAuth-Only 模式章节配置结构体定义在 config/config.goOAuthOnly bool \yaml:oauth_only。3.4 浏览器扩展认证浏览器扩展有两种认证方式个人访问令牌在扩展弹窗popup或选项页options page中输入令牌并保存设置复制浏览器会话先在同一个浏览器中登录 Hister Web 界面点击扩展弹窗或选项页中的Authenticate with Browser Session按钮扩展会复制 Web 界面当前活跃的会话 Cookie。所有经扩展索引的页面都会存入该用户的账号之下文档归属由认证用户 ID 决定见「文档隔离」。3.5 API 与命令行客户端认证任何 API 客户端都可以通过X-Access-Token请求头携带个人访问令牌完成认证curl -H X-Access-Token: your-token http://localhost:4433/api/statsHister CLI 使用-t标志传入令牌hister -t your-token search query在源码层面令牌认证有两套路径请求头X-Access-Token以及Authorization: Bearer token形式见 server/server.go 的requestAccessToken。认证后populateUserContext会依据令牌查询用户并填充用户上下文server/server.go。四、用户管理命令所有用户管理命令都要求user_handling: true并且需要能直接访问服务器主机它们会直接更新用户数据库因此不应在远程通过 API 暴露。其中delete-user还会联系正在运行的 Hister 服务器搜索该用户拥有的文档并在提供--purge时通过 API 删除它们。命令实现在 cmd/users.go 中对应的数据库操作在 server/model/user.go 中。4.1 create-user创建新用户账号交互式提示输入密码最少 8 个字符需输入两次确认。hister create-user USERNAME [--admin]标志说明--admin授予该用户管理员权限底层实现model.CreateUser使用bcrypt默认成本对密码加盐哈希后存储并生成随机访问令牌server/model/user.go。密码在 cmd/users.go 的promptConfirmedPassword中完成长度校验少于 8 字符直接报错与两次输入一致性校验并通过交互式 TUI 以*回显输入。4.2 delete-user软删除用户账号。若服务器发现该用户拥有已索引的文档除非提供--purge否则命令拒绝继续--purge会在软删除账号前先删除预检preflight发现的文档。需要注意这不是完整的数据擦除关于多用户所有权与数据保留的细节见>hister delete-user USERNAME [--purge]标志说明--purge先删除该用户名下找到的已索引文档再删除账号源码逻辑cmd/users.go命令先用user_id:ID查询该用户的文档数若Total 0且未提供--purge则直接退出并提示提供--purge时调用DeleteDocuments清理文档最后执行model.DeleteUser软删除。4.3 show-user显示用户账号信息。hister show-user USERNAME [--token]标志说明--token同时显示该用户的访问令牌默认隐藏示例输出Username: alice ID: 1 Admin: yes Created at: 2026-03-26 09:00:00 Updated at: 2026-03-26 09:00:004.4 update-user修改既有用户账号至少必须提供一个标志。hister update-user USERNAME [--username NEW] [--password] [--regen-token] [--toggle-admin]标志说明--username NEW将用户名改为NEW--password交互式提示并设置新密码--regen-token生成并打印新访问令牌旧令牌立即失效--toggle-admin切换管理员状态开/关标志可以组合使用当--username与其他标志一起使用时先执行改名cmd/users.go 中先调用model.UpdateUsername再继续后续标志处理。密码同样要求至少 8 个字符并输入两次确认。未提供任何标志时命令会报错no changes specified退出cmd/users.go。五、每用户规则与别名开启用户处理后每个用户的规则与别名独立存储于数据库不是配置文件。通过 Web UI 或 API 的修改只影响当前认证用户的规则不会改动配置文件。Skip rules跳过规则命中用户跳过规则的 URL 在索引时被静默忽略与单用户模式行为一致Priority rules优先规则用户的优先规则将匹配结果提升到其搜索结果顶部Versioning rules版本化规则命中版本化规则的 URL 在每次重新索引时对其内容做 diff 并保存Search aliases搜索别名用户定义的别名仅作用于该用户的搜索。用户可以通过 Web 界面的Rules标签页或 API 端点查看和编辑自己的规则与别名。而单用户模式下规则与别名继续从应用数据目录下的rules.json读写。底层实现用户模型中的RulesJSON字段以 JSON 形式存储规则默认{}ParseRules在读取时反序列化并补齐缺失的 Skip/Priority/Versioning 与 Aliases 字段然后调用Compile()编译正则SaveUserRules将规则序列化写回数据库server/model/user.go。在请求处理中webContext.effectiveRules()会优先返回认证用户的规则server/server.go。六、规则正则语法Regexp规则正则的匹配行为对实际配置至关重要以下是官方文档明确的行为约定跳过规则作用于完整的 URL从协议到查询字符串参数并且匹配范围是受限的锚定必须包含协议例如^https://foo.com或^https?://(login|mail)\.是合法的而^foo.com无法命中/login$不会匹配https://foo.com/login?auth1因为 URL 还带有查询字符串URL 中的 hash 会被移除https://foo.com/#active-tab归一化为https://foo.com/查询字符串参数不会被重排仅剥离utm_*参数Go 正则表达式regexp/syntax语法不支持 look-ahead / look-behind前瞻/后瞻断言。这些约定在规则编译与 URL 归一化流程中生效见 config/config.go 的Rules结构与规则编译逻辑编写规则时务必留意。七、管理员用户管理员Admin用户拥有特权操作权限。目前以下端点要求管理员权限POST /api/reindex重建整个全文搜索索引POST /api/cleanup移除不再匹配所配置目录的本地文档并删除没有任何当前文档引用的已存 HTML 与 favicon 文件。非管理员用户调用仅管理员端点会收到403 Forbidden。端点到权限的映射在 server/endpoints.go 中实现当userHandling开启且端点需要认证时AdminOnly端点套用withAdminAuth其余套用withUserAuth而 server/server.go 的withAdminAuth会检查UserID 0未登录与IsAdmin两个条件任一不满足即返回 403。管理员状态可在创建时授予create-user --admin也可随时切换update-user --toggle-admin底层为 server/model/user.go 的ToggleAdmin。另外多用户模式下管理员可通过X-Hister-Target-User-ID请求头以其他用户身份执行操作server/server.go 的targetUserID。八、单用户兼容与存量数据迁移Hister保留用户 ID0用于未认证匿名场景。未开启用户处理时索引的文档存储于用户 ID0之下开启功能后这些文档仍然对所有已认证用户可见。这意味着你可以在既有实例上开启用户处理而不会丢失对之前索引内容的访问。若想把既有的全局文档收归某个特定用户私有流程如下用hister show-user USERNAME找到该用户的数字 ID以管理员身份执行查询更新hister update user_id:0 --user-id USER_ID几点注意事项先加--dry预览受影响的文档数量当该用户已经拥有相同 URL 时所有权冲突会被跳过被监视的本地文件watched local files需要目录配置中的user值与新所有者一致——该配置字段见 config/config.go 的Directory.User文件索引队列会依据它确定归属用户server/indexer/files.go 的directoryUserID。九、文档隔离与搜索作用域每个用户的已索引文档都携带其用户 ID 存储。搜索自动限定在以下范围内由当前已认证用户索引的文档未开启用户处理时索引的文档用户 ID0它们作为共享的只读基线对所有用户可见。用户之间无法看到彼此的文档。首页显示的文档计数反映的是当前认证用户自己的文档数而非所有用户的总数。源码佐证查询构建在 server/indexer/history.go 的latestDocumentsQuery中当userID 0时为查询附加user_id字段过滤否则走全局查询写入侧 server/indexer/files.go 的IndexFile接收userID参数并写入文档记录。单文件索引时以GetByURLAndUser(fileURL, userID)区分归属确保同一 URL 在不同用户下可独立存在。十、公共模式Public Mode当app.public: true与用户处理同时启用时匿名访客只能搜索用户 ID0下的全局文档具名用户拥有的文档对匿名访客保持私有仅对各自已认证用户可见已认证用户依然可以按正常规则添加、删除、打标签、管理自己的内容并访问自己的 Web 历史Web 历史对匿名访客不可用源码见 server/server.go 的historyEnabled!c.Config.App.Public || c.Authenticated。配置合法性校验在 config/config.go 的ValidatePublicMode启用public时必须同时配置app.access_token或app.user_handling否则报错app.public requires app.access_token or app.user_handling。十一、个人访问令牌每个用户账号都有一个用于 API 认证的个人访问令牌。令牌是随机生成的存储在数据库中server/model/user.go 使用crypto/rand的rand.Text()RegenerateToken同理。从 Web UI 生成Profile → Generate Token命令行hister update-user --regen-token生成新令牌会立即作废旧令牌——记得同步更新所有客户端浏览器扩展、脚本show-user默认不显示令牌需要--token标志才会揭示。令牌认证路径在 server/model/user.go 的GetUserByToken中按明文 token 精确匹配数据库记录为降低泄露风险建议将令牌视为机密妥善保管并在可能泄露时及时重新生成。十二、安全考量汇总密码使用bcrypt加盐哈希后存储默认成本任何 API 都不会返回密码User.Password带json:-标签server/model/user.go浏览器 Cookie只包含随机会话标识符会话数据与标识符哈希存储在配置的 SQL 数据库中登出会立即撤销数据库中的会话记录个人访问令牌绕过会话 Cookie可用于脚本。请保密保存泄露后立即重新生成OAuth state 令牌单次使用的随机值存储在服务端会话中用于防止 OAuth 重定向流程中的跨站请求伪造CSRFOAuth 登录默认使用 S256 PKCE私有 verifier 将授权请求绑定到其令牌交换与 state 和提供方信息一起存储在服务端会话中。老旧提供方的兼容配置与升级行为见 configuration.mdOAuth 账号没有密码管理员可用hister update-user USERNAME --password为其分配密码如需停用某个 OAuth 用户的访问用hister delete-user删除账号或从配置中移除对应提供方强制 OAuth启用server.oauth_only: true可禁止密码认证个人访问令牌对 API 与 CLI 依然有效。多用户模式下app.access_token必须包含某个用户的个人令牌适用场景边界用户处理面向同一实例上的可信用户群体家庭、团队。对公网部署应将 Hister 置于带 HTTPS 的反向代理之后并且只索引允许公开展示的内容。十三、快速上手清单在配置文件的app段设置user_handling: true按需配置server.oauth可选与app.public重启 Hister 服务器在服务器主机上执行hister create-user USERNAME需要管理员就用--admin创建首个账号通过 Web 界面用用户名/密码或 OAuth 登录并在 Profile 页生成个人访问令牌用hister -t your-token search query或curl -H X-Access-Token: your-token ...验证 API 认证按需使用update-user --toggle-admin/--regen-token管理账号用delete-user --purge彻底清理用户及其文档。至此你已经掌握了 Hister 多用户模式从配置、认证、命令管理到文档隔离与安全的完整体系。更进一步可以结合 configuration.md 的 OAuth 与 PKCE 章节、data-lifecycle.md 的多用户所有权章节以及 cmd/users.go 与 server/model/user.go 的源码继续深入。赞分享搜索引擎全文检索后端前端CLI【免费下载链接】histerYour own search engine项目地址https://gitcode.com/GitHub_Trending/hi/hister点击查看免费下载相关推荐Ling-2.0到Ling-2.6的进化之路万亿模型的架构迁移与优化策略Ling 2.0到Ling 2.6的进化之路万亿模型的架构迁移与优化策略 Ling 2.6 1T base 作为新一代万亿参数语言模型代表了从Ling分布式AI工程平台架构深度解析Langfuse多语言支持与国际化部署实战分布式AI工程平台架构深度解析Langfuse多语言支持与国际化部署实战 Langfuse作为开源AI工程平台为LLM应用提供全面的可观测性、评估、指标监控人工智能LLMOps可观测性AI 评测LLM 网关后端前端一台电脑玩遍 800 多款联机游戏Nucleus Co-op 本地分屏工具完整上手指南一台电脑玩遍 800 多款联机游戏Nucleus Co op 本地分屏工具完整上手指南 周末朋友突然上门想一起打游戏可客厅里只有一台电脑、一份游戏。这个画游戏开发桌面应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考