ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

WeKan 用户管理 REST API 实战指南:注册、创建、查询、禁用与删除

WeKan 用户管理 REST API 实战指南:注册、创建、查询、禁用与删除 WeKan 用户管理 REST API 实战指南注册、创建、查询、禁用与删除【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan本指南以 WeKan 官方 API 文档docs/API/User.md为主线系统讲解用户生命周期管理的全部 REST 端点从无需认证的用户自助注册、管理员创建/删除用户、查询用户信息与用户列表到通过 PUT 动态禁用/启用登录。阅读后你将能够独立编写 curl 脚本或集成代码完成对 WeKan 实例用户的完整增删改查并理解每个端点背后的权限模型与安全边界。环境前提与认证模型开启 REST APIWeKan 的 REST API 由WITH_API环境变量控制。从 server/apiMiddleware.js 的 API 网关逻辑可见所有/api前缀请求在WITH_API ! true时直接返回 HTTP 403 纯文本说明而不是重定向——这意味着 API 关闭时导出 PDF、Excel、CSV 等依赖/api/...地址的功能同样不可用。因此使用本指南前请先确认实例以WITH_APItrue启动。# 示例以环境变量方式启动 WITH_APItrue node main.jsToken 获取与传递文档反复强调You will need to provide thetokenfor any of the authenticated methods.。Token 的获取方式有两种首次登录即返回 tokenPOST /users/register在成功创建账户时直接返回token与tokenExpires无需再次登录。显式登录调用POST /users/login成功后返回同样的id / token / tokenExpires结构实现在 server/apiAuthRoutes.js。Token 通过Authorization: Bearer token请求头携带。底层解析逻辑位于 server/apiMiddleware.js中间件先读取Authorization: Bearer xxx请求头若不存在则回退到access_token查询参数随后用Accounts._hashLoginToken对 token 做哈希在services.resume.loginTokens.hashedToken中匹配用户匹配成功则把用户 id 写入req.userId。管理员判定文档在 User Information 与 User List 两节特别注明Only the admin user (the first user) can call the REST API. 源码印证了这一规则server/authentication.js 中Authentication.checkUserId只做两件事——未携带 token 抛 401Unauthorizedtoken 对应用户不是isAdmin: true时抛 403Forbidden。因此第一个注册成功的用户是站点管理员isAdmin: true所有标有 Requires Admin Auth 的端点都必须使用管理员账号的 token。另外注意 server/apiAuthRoutes.js 的登录节流REST 登录路径不经过 DDP 层的 accounts-lockout 钩子因此单独实现了按客户端地址计数的失败节流REST_LOGIN_MAX_FAILURES、REST_LOGIN_FAILURE_WINDOW_SECONDS、REST_LOGIN_LOCKOUT_SECONDS三个环境变量可调连续失败会返回 429 并携带Retry-After响应头。这对集成脚本设计重试逻辑很重要。用户自助注册POST /users/register该端点无需认证用于公开注册。URLRequires AuthHTTP Method/users/registernoPOSTPayloadArgumentExampleRequiredDescriptionusernamemyusernameRequired用户名passwordmy$up3erPssw0rdRequired密码emailmyemail.comRequired邮箱示例调用 —— Form Datacurl http://localhost:3000/users/register \ -d usernamemyusernamepasswordmypasswordemailmyemail.com示例调用 —— JSONcurl -H Content-type:application/json \ http://localhost:3000/users/register \ -d { username: myusername, password: mypassword, email: myemail.com }响应{ id: user id, token: string, tokenExpires: ISO encoded date string }响应示例{ id: XQMZgynx9M79qTtQc, token: ExMp2s9ML1JNp_l11sIfINPT3wykZ1SsVwg-cnxKdc8, tokenExpires: 2017-12-15T00:47:26.303Z }源码级解读注册处理器位于 server/apiAuthRoutes.js其关键行为包括参数校验使用check(options, {...})校验请求体username与email为可选项、password必填Match.OptionalString类型约束。受禁用注册开关约束这是本项目近期修复的一个安全漏洞SignupBleed。旧实现读取的forbidClientAccountCreation在 WeKan 中从未被设置导致管理后台关闭注册后该端点依旧开放。现在处理器改为读取ReactiveCache.getCurrentSetting()中的disableRegistration字段为true时记录安全日志authz.register分类并返回HTTP 403。对应回归测试见 tests/restRegisterRespectsSetting.test.cjs。创建与签发 token调用Accounts.createUserAsync(userOptions)建号随后Accounts._generateStampedLoginToken()生成登录令牌、Accounts._insertLoginToken写入用户文档并计算Accounts._tokenExpiration作为过期时间——这就是响应中token与tokenExpires的来源。创建限速server/models/users.js 中注册了 DDP 方法级限速每个客户端地址每 60 秒最多 10 次createUser调用防止注册接口被批量轰炸。管理员创建用户POST /api/usersURLRequires Admin AuthHTTP Method/api/usersyesPOSTPayloadArgumentExampleRequiredDescriptionusernamemyusernameRequired用户名passwordmy$up3erPssw0rdRequired密码emailmyemail.comRequired邮箱示例调用 —— Form Datacurl -H Authorization: Bearer a6DM_gOPRwBdynfXaGBaiiEwTiAuigR_Fj_81QmNpnf \ -X POST \ http://localhost:3000/api/users \ -d usernamemyusernamepasswordmypasswordemailmyemail.com示例调用 —— JSONcurl -H Authorization: Bearer a6DM_gOPRwBdynfXaGBaiiEwTiAuigR_Fj_81QmNpnf \ -H Content-type:application/json \ -X POST \ http://localhost:3000/api/users \ -d { username: myusername, password: mypassword, email: myemail.com }响应返回新用户的 id{ _id: user id }响应示例{ _id: EnhMbvxh65Hr7YvtG }源码级解读处理器位于 server/models/users.js首先await Authentication.checkUserId(req.userId)确认调用者是管理员然后调用Accounts.createUser({ username, email, password, from: admin })创建账户from: admin标记该账户由管理员后台创建文档补充说明该端点在自注册开启或关闭时都可用——因为它是管理员显式授权操作不受disableRegistration设置影响可作为企业内部管理员代开账号的标准通道。管理员删除用户DELETE /api/users/:id重要提示文档注明在 issue #1289不会清理该用户在卡片、评论中的历史引用可能留下脏数据。若需求是移除访问权限但保留历史记录更推荐使用下方的disableLogin禁用方式或在管理界面使用匿名化anonymize替代方案见Meteor.methods.anonymizeUserserver/models/users.js。URLRequires Admin AuthHTTP Method/api/users/:idyesDELETE参数ArgumentExampleRequiredDescriptionidBsNr28znDkG8aeo7WRequired要删除的用户 id示例调用curl -H Authorization: Bearer a6DM_gOPRwBdynfXaGBaiiEwTiAuigR_Fj_81QmNpnf \ -X DELETE \ http://localhost:3000/api/users/EnhMbvxh65Hr7YvtG响应返回被删除用户的 id{ _id: EnhMbvxh65Hr7YvtG }源码级解读与测试验证该端点的行为被 tests/restUserDelete.test.cjs 用独立的 Node 脚本完整固定值得关注先鉴权后删除Authentication.checkUserId抛错时根本不会触达removeAsync测试第 155-174 行验证非管理员返回 403删除计数校验removeAsync返回 0 表示用户不存在返回HTTP 404而非静默成功返回值异常如 2则抛错转 500避免误报测试第 108-136 行数据库故障同样被捕获为 500而不会让进程崩溃。查询用户信息GET /api/users/:idURLRequires Admin AuthHTTP Method/api/users/:idyesGET示例调用curl -H Authorization: Bearer a6DM_gOPRwBdynfXaGBaiiEwTiAuigR_Fj_81QmNpnf \ http://localhost:3000/api/users/XQMZgynx9M79qTtQc响应示例{ _id: XQMZgynx9M79qTtQc, createdAt: 2017-09-13T06:45:53.127Z, services: { password: { bcrypt: $2a$10$CRZrpT4x.VpG2FdJxR3rN.9m0NbQb0OPsSPBDAZukggxrskMtWA8. }, email: { verificationTokens: [ { token: 8rzwpq_So2PVYHVSfrcc5f5QZnuV2wEtu7QRQGwOJx8, address: myemail.com, when: 2017-09-13T06:45:53.157Z } ] }, resume: { loginTokens: [ { when: 2017-09-13T06:45:53.265Z, hashedToken: CY/PWeDa3fAklk94GWzCtpB5nPcVxLzzzjXs4kI3A }, { when: 2017-09-16T06:06:19.741Z, hashedToken: 74MQNXfsgjkItx/gpgPb29Y0MSNAvBrsnSGQmr4YGvQ } ] } }, username: john, emails: [ { address: myemail.com, verified: false } ], isAdmin: true, profile: {} }源码级解读处理器位于 server/models/users.js支持按用户名查询req.params.userId首先按_id查查不到则回退按username查代码中ReactiveCache.getUser({ username: id })所以 URL 中的 id 位置实际上可以传用户名附带成员关系响应会额外携带boards数组列出该用户在所有看板上的成员角色boardId 各权限标志便于调用方判断用户在看板体系中的权限机密字段剥离由于历史漏洞 GHSA-6qpx-x7vr-p9w6管理员 API 曾泄露services.password.bcrypt密码哈希与全部会话令牌现在所有管理端用户响应都会经过withoutSecrets()过滤server/models/users.js删除services与sessionData子树。注意上文响应示例是旧版文档的原始输出当前仓库已不再返回services字段。查询用户列表GET /api/usersURLRequires Admin AuthHTTP Method/api/usersyesGET示例调用curl -H Authorization: Bearer cwUZ3ZsTaE6ni2R3ppSkYd-KrDvxsLcBIkSVfOCfIkA \ http://localhost:3000/api/users响应[ { _id: user id, username: string } ]响应示例[ { _id: XQMZgynx9M79qTtQc, username: admin }, { _id: vy4WYj7k7NBhf3AFc, username: john } ]源码级解读处理器位于 server/models/users.js。它通过Authentication.checkUserId鉴权后用Meteor.users.find({}, { fields: { _id: 1, username: 1 } })投影只取_id和username两个字段再逐条映射输出。因此该端点永远不会返回邮箱、密码哈希等敏感信息适合作为用户名/id 对照表用于后续批量操作例如拿到 id 后逐一 GET 详情或 PUT 禁用。查询当前登录用户GET /api/userURLRequires AuthHTTP Method/api/useryesGET与上面的管理员端点不同此端点只需登录、不需管理员返回当前 token 对应用户自身的信息。处理器位于 server/models/users.js使用Authentication.checkLoggedIn(req.userId)仅校验已登录然后删除services字段、附加自己的看板成员列表后返回。示例调用curl -H Authorization: Bearer a6DM_gOPRwBdynfXaGBaiiEwTiAuigR_Fj_81QmNpnf \ http://localhost:3000/api/user响应示例{ _id: vy4WYj7k7NBhf3AFc, createdAt: 2017-09-16T05:51:30.339Z, username: john, emails: [ { address: memail.com, verified: false } ], profile: {} }禁用与启用用户PUT /api/users/:id这是不删除数据、仅冻结账号的标准手段禁用后用户无法登录且其全部登录令牌会被清除启用后恢复。URLRequires Admin AuthHTTP Method/api/users/:idyesPUT禁用用户curl -H Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl \ -H Content-type:application/json \ -X PUT \ http://localhost:3000/api/users/ztKvBTzCqmyJ77on8 \ -d { action: disableLogin }启用用户curl -H Authorization: Bearer t7iYB86mXoLfP_XsMegxF41oKT7iiA9lDYiKVtXcctl \ -H Content-type:application/json \ -X PUT \ http://localhost:3000/api/users/ztKvBTzCqmyJ77on8 \ -d { action: enableLogin }源码级解读处理器位于 server/models/users.js动作由请求体中的action字段区分disableLogin对目标用户$set: { loginDisabled: true, services.resume.loginTokens: }—— 既打上禁用标记又清空所有会话令牌文档注释明确说明 his login tokens are purged实现立即强制下线。源码同时防止管理员禁用自己id ! req.userId条件。enableLogin$set: { loginDisabled: }清除禁用标记。配合 server/authentication.js 中Accounts.validateLoginAttempt的钩子return !user.loginDisabledloginDisabled字段对所有登录方式本地密码、LDAP、OIDC 等统一生效。该端点同样接受额外动作takeOwnership接管目标用户管理的看板从源码可见它是删除管理员场景的配套操作本指南不展开。完整实战管理员创建用户的四步流程官方文档给出了一条端到端链路这里保留原文步骤并补充注释1) 登录获取管理员 tokencurl http://example.com/users/login \ -d usernameYOUR-USERNAME-HEREpasswordYOUR-PASSWORD-HERE响应返回你的id与tokenid:YOUR-ID-HERE,token:YOUR-TOKEN-HERE,tokenExpires:2017-12-23T21:07:10.395Z}2) 创建用户自注册开启或关闭时均可用curl -H Authorization: Bearer YOUR-TOKEN-HERE \ -H Content-type:application/json \ -X POST \ http://example.com/api/users \ -d { username: tester, password: tester, email: testerexample.com, fromAdmin: true }响应返回新用户的 id{id:NEW-USER-ID-HERE}3) 用新用户 id 查询其详情curl -H Authorization: Bearer YOUR-TOKEN-HERE \ http://example.com/api/users/NEW-USER-ID-HERE4)可选冻结或删除需要临时冻结时改用第 3 步的 token 执行 PUT{action:disableLogin}确需永久删除再走 DELETE。整个流程中token 只应来自第 1 步的管理员账号否则所有管理端点都会返回 403。常见问题与安全提醒401 vs 403未携带或携带无效 token 时管理端点返回 401Unauthorizedtoken 有效但非管理员时返回 403Forbidden见 server/authentication.js。响应体不是直接可用的对象当前源码中所有 API 处理器统一用sendJsonResult输出{ code: 200, data: {...} }结构server/apiMiddleware.js集成脚本需读取data字段这与文档中旧版的裸对象示例存在差异请以实际响应为准。注册开关联动POST /users/register受管理后台禁用注册设置约束返回 403而管理员POST /api/users不受影响。敏感数据最小化GET /api/users只返回_id/username管理端详情接口会剥离services与sessionData任何调用方都无法通过 REST API 获取密码哈希或会话令牌。删除需谨慎DELETE 是硬删除且存在历史问题issue #1289生产环境优先考虑disableLogin禁用或匿名化方案。代码即文档深入模型层文档结尾指引读者直接阅读模型源码In Wekan code 一节指向 models/users.js原文档相对链接../../models/users.js对应仓库根目录的该文件其中定义了用户集合的完整 Schema 与各类帮助方法。与本文 REST 端点直接相关的服务端实现则位于server/models/users.js/api/users系列全部 REST 处理器列表、详情、创建、删除、PUT 禁用/启用server/apiAuthRoutes.js/users/register、/users/login、/users/logoutserver/apiMiddleware.jsBearer token 解析、WITH_API网关、sendJsonResult响应封装server/authentication.js管理员鉴权与登录校验钩子tests/restUserDelete.test.cjs 与 tests/restRegisterRespectsSetting.test.cjs删除行为与注册开关的回归测试对照阅读可确认本文涉及的每个端点行为均有源码与测试双重印证可放心用于实际集成开发。【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表