Repository navigation
feat(auth): sys_user 批量导入接口 —— 导入用户的密码处理策略 #2758
Copy link
Copy link
Closed
Labels
Description
背景
sys_user 是 managedBy:'better-auth' 对象,CRUD affordances 里 create/import/edit/delete 全 false(见 packages/spec/src/data/object.zod.ts 的 CRUD_AFFORDANCE_DEFAULTS),所以 Console 列表没有「新增/导入」,平台通用导入向导对它也被禁用。目前批量建号只能靠脚本循环调 better-auth 单条接口。
- better-auth 协议本身无批量 import 原语,只有单条:
admin插件的/admin/create-user、/admin/list-users、/admin/set-role、/admin/set-password(核实better-auth@1.6.23plugins/admin/routes.mjs);核心/sign-up/email。 - 已有通用列表导入 issue feat(import): 产品级列表导入(L0–L4:批量/dryRun、Upsert 改记录、导入模板、异步 Job、校验审计) #2504(L0–L4 批量/dryRun/Upsert/模板/异步 Job/校验审计)、对象列表视图:新增「导出」+ 改进「导入」的校验与数据完整性 #2460(导出+导入校验),但都是普通业务对象的导入,没覆盖身份对象的凭据/密码这一层。
诉求
提供 sys_user(身份对象)专用的批量导入接口,把 Excel/CSV 里的员工批量建成可登录账号。核心难点是导入用户的密码怎么处理。
核心决策点:密码处理策略(必须先定)
导入的用户需要一份可登录凭据,四种策略,建议支持多种、按导入任务选:
-
无密码 + 首登引导(最安全,推荐默认)
- 建号时不设密码,批量发邀请/魔法链接/重置密码邮件,用户首次点链接自设密码。
- 依赖邮件服务(未配 EmailService 会静默失败,需在导入结果里显式标记发送失败的行)。
- 无邮箱的员工无法走此路 → 与 feat(auth): 支持用户名/工号登录 —— 接入 better-auth username 插件 #2756 用户名登录 + 短信 OTP 关联。
-
管理员统一临时密码 + 强制改密
- 导入时给一个(或每人随机生成的)临时密码,落
requirePasswordChange标记,首登强制改。 - 需要平台支持"强制改密"标记与拦截(当前是否有?待确认;better-auth 无内置
requirePasswordChange,可能要自研 before-hook)。 - 临时密码的下发渠道(导出一次性 CSV?邮件?)要定,且绝不落日志。
- 导入时给一个(或每人随机生成的)临时密码,落
-
导入历史系统的预哈希密码(迁移场景)
- 老系统迁移时希望用户沿用原密码。better-auth 默认 scrypt;要接受外部哈希需配置自定义
emailAndPassword.password.hash/verify(better-auth 支持自定义 hasher)。 - 需支持声明哈希算法/参数;不同算法混存要能区分。复杂度最高,列为可选高级能力。
- 老系统迁移时希望用户沿用原密码。better-auth 默认 scrypt;要接受外部哈希需配置自定义
-
随机密码 + 不下发(仅占位,用户只能靠重置登录)—— 一般不单独用,作为 1/2 的兜底。
接口设计建议
- 新增身份专用导入端点(如
POST /api/v1/auth/admin/import-users),而非放开 sys_user 的通用 import affordance——因为要走 better-auth 的建号/哈希管线,不能直接 insert。 - 入参:
rows[](email/username/name/role/...)、passwordStrategy(上面 1–4)、dryRun、upsert(按 email/username 幂等)、可选sendInvitation。 - 复用通用导入框架的能力:dryRun、逐行校验报告、异步 Job、导入审计(对齐 feat(import): 产品级列表导入(L0–L4:批量/dryRun、Upsert 改记录、导入模板、异步 Job、校验审计) #2504,避免重造)。
- 安全:密码/哈希字段禁止进日志/审计明文;权限 gate(仅
manage_platform_settings等);限流。 - 幂等:重复导入按 email/username upsert,不产生重复账号(参考记忆:insert 种子无 predev 清库会重复的教训)。
决策点(需拍板)
- 默认策略选 1(邀请/首登设密)还是 2(临时密码+强制改密)?
- 是否需要支持策略 3(预哈希迁移)?若要,自定义 hasher 的配置形态。
- 「强制改密」标记是否已有平台支持?没有的话作为前置子任务。
- 是走独立
import-users端点,还是扩展 feat(import): 产品级列表导入(L0–L4:批量/dryRun、Upsert 改记录、导入模板、异步 Job、校验审计) #2504 通用导入 + 给身份对象加"凭据后处理"钩子?建议前者(身份管线特殊)。
影响面
packages/plugins/plugin-auth(导入端点 + 密码策略 + 邀请/重置复用)- 可能触及
emailAndPassword.password.hash/verify(策略 3) - 与通用导入框架 feat(import): 产品级列表导入(L0–L4:批量/dryRun、Upsert 改记录、导入模板、异步 Job、校验审计) #2504 的能力复用/边界划分
相关
- feat(import): 产品级列表导入(L0–L4:批量/dryRun、Upsert 改记录、导入模板、异步 Job、校验审计) #2504 产品级列表导入(通用对象)
- 对象列表视图:新增「导出」+ 改进「导入」的校验与数据完整性 #2460 列表导入校验/完整性
- feat(auth): 支持用户名/工号登录 —— 接入 better-auth username 插件 #2756 用户名/工号登录(无邮箱员工的导入与登录强相关)
Reactions are currently unavailable
Activity
feat(auth): 管理员直建用户 + 手机号登录 + sys_user 批量导入(#2766 V1/V1.5/V2) (#2771)