ARTICLE DETAIL

资讯详情

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

TREK 登录与注册完全指南:会话 Cookie、密码策略、邀请链接、限流与 SSO 实战解析

TREK 登录与注册完全指南:会话 Cookie、密码策略、邀请链接、限流与 SSO 实战解析 TREK 登录与注册完全指南会话 Cookie、密码策略、邀请链接、限流与 SSO 实战解析【免费下载链接】TREKA self-hosted travel/trip planner with real-time collaboration, interactive maps, PWA support, SSO, budgets, packing lists, and more.项目地址: https://gitcode.com/GitHub_Trending/nomad22/TREKTREK 是一个可自托管的旅行行程规划器其登录/注册体系覆盖从密码认证、双因素认证MFA、邀请链接注册、强制改密、按 IP 限流到 OIDC SSO 的完整身份链路。本文以 wiki/Login-and-Registration.md 为骨架结合前端登录页实现与后端认证服务源码逐层剖析会话 Cookie 的属性与有效期、密码校验规则、注册的三种触发条件、四类限流阈值以及 Demo 模式与 SSO 的交互细节帮助你理解并正确配置 TREK 实例的身份入口也能据此排查“登录后反复 401”“明文 HTTP 下 Cookie 丢失”等自托管常见问题。登录流程与会话 Cookie访问/login并提交凭据导航到/login后TREK 前端client/src/pages/LoginPage.tsx会先调用GET /api/auth/app-config获取实例级配置是否已有用户、是否开放注册、是否配置了 OIDC、是否启用 Demo 等见 server/src/services/authService.ts 的getAppConfig再决定渲染登录表单、注册表单或直接跳转 SSO。输入邮箱与密码提交后请求命中POST /api/auth/loginserver/src/nest/auth/auth-public.controller.ts。服务端通过 bcrypt成本因子 12见 server/src/services/authService.ts比对密码哈希成功后签发 JWT 会话令牌并通过Set-Cookie写入trek_session。trek_sessionCookie 的关键属性会话 Cookie 的构造集中在 server/src/services/cookie.ts核心属性如下属性值含义httpOnlytrue脚本无法读取防御 XSS 窃取会话sameSitelax允许顶级导航携带 Cookie同时缓解 CSRFsecure生产环境为true仅通过 HTTPS 传输详见下文maxAge默认SESSION_DURATION_MS会话有效期与 JWT 的exp声明保持一致path/全站生效24 小时会话与 Remember me默认情况下一次登录产生的会话有效期为24 小时刷新页面、关闭浏览器重启都不会失效直到会话过期或显式登出。这个默认值来自 server/src/config.ts 中的DEFAULT_SESSION_DURATION 24h。SESSION_DURATION环境变量可覆盖默认会话时长支持ms/s/m/h/d/w/y单位的 ms 风格字符串例如SESSION_DURATION7d。配置解析在启动时进行非法值会告警并回退到24h。Remember me记住我登录表单上的开关对应SESSION_DURATION_REMEMBER默认30 天server/src/config.ts。实现上rememberMe同时影响两处JWT 的expiresIn与 Cookie 的maxAgeserver/src/services/authService.ts 的generateToken、server/src/services/cookie.ts 的resolveMaxAge两者永远同步、不会漂移。未勾选 Remember me 时Cookie 不携带maxAge属于浏览器会话级 Cookie关闭浏览器即清除server/src/services/cookie.ts。注意secure标志可用COOKIE_SECUREfalse显式关闭适合纯 HTTP 的开发环境也可用FORCE_HTTPStrue强制开启。此外server/src/services/cookie.ts 的实现会额外检查req.secureExpress 在trust proxy开启时由X-Forwarded-Proto推导——也就是说即使本地NODE_ENVdevelopment且未设FORCE_HTTPS只要请求经由 Traefik/Caddy/Cloudflare Tunnel 等 HTTPS 反代进入Cookie 同样会带上Secure标志这正是不少自托管用户忽略的细节。明文 HTTP 下的 Cookie 丢失陷阱若服务端即将下发带Secure标志的 Cookie而请求本身并非 HTTPS浏览器会静默丢弃 Cookie导致下一个请求直接返回 “Access token required”。为此 TREK 在登录响应中附带insecureCookie: true标志server/src/nest/auth/auth-public.controller.ts前端检测到后会在登录页展示黄色提示条指导你改用 HTTPS 或设置COOKIE_SECUREfalse见 client/src/pages/LoginPage.tsx而不是让你面对一个莫名其妙的 401。双因素认证MFA登录如果账号已启用 2FA密码校验通过后不会立即下发会话 Cookie而是返回{ mfa_required: true, mfa_token }server/src/services/authService.ts。这个mfa_token是有效期仅5 分钟的短期 JWTpurpose: mfa_login专门用于承载后续的 MFA 验证步骤与会话令牌相互隔离。前端收到mfa_required后切换到 TOTP 输入界面client/src/pages/login/useLogin.ts支持TOTP 验证码来自你绑定的 Authenticator 应用备用恢复码backup code8 位字符输入时自动转大写并去除非字母数字字符server/src/services/authService.ts 的normalizeBackupCode。验证请求走POST /api/auth/mfa/verify-loginserver/src/nest/auth/auth-public.controller.ts成功后才会真正写入trek_session会话 Cookie并记录user.login审计事件。MFA 验证单独限流为每 IP 每 15 分钟 5 次。忘记密码与强制改密忘记密码自助流程登录表单下方的“Forgot password?”链接启动自助重置流程完整细节见 wiki/Password-Reset.md。服务端实现上POST /api/auth/forgot-passwordserver/src/nest/auth/auth-public.controller.ts无论邮箱是否存在都返回统一的{ ok: true }响应并强制等待至少 350msFORGOT_MIN_LATENCY_MS以消除账号枚举的时间侧信道POST /api/auth/reset-password则负责校验重置令牌并写入新密码。强制密码更改Forced password change当管理员将账号标记为“必须修改密码”时数据库中must_change_password字段为 1成功登录或 MFA 步骤完成后TREK 会直接展示Set new password表单且不会签发会话 Cookie直到新密码保存成功登录接口返回的用户对象带有must_change_password: trueserver/src/services/authService.ts前端捕获该标志进入passwordChangeStep状态client/src/pages/login/useLogin.ts提交新密码走POST /api/auth/change-password成功后才会loadUser并跳转client/src/pages/login/useLogin.ts。服务端在执行改密时同样会走validatePassword密码强度校验并更新password_version、清除must_change_passwordserver/src/services/authService.ts。password_version的存在意味着改密后旧令牌即刻失效——这正是会话安全模型的关键一环。注册流程注册表单出现的三种条件TREK 的注册表单只在以下任一条件成立时展示开放注册管理员为实例启用了密码注册password_registration设置项。该开关在 server/src/services/authService.ts 的resolveAuthToggles中解析可由数据库app_settings表或环境变量控制且在 Demo 模式下被强制关闭server/src/services/authService.ts。有效的邀请链接访问/login?inviteTOKEN且令牌有效详见下文“邀请链接流程”。首个用户实例中尚不存在任何账号注册表单自动展示。前端逻辑与之一一对应useLogin启动时解析invite查询参数、拉取app-config若has_users false则直接切换到注册模式client/src/pages/login/useLogin.ts 与 client/src/pages/login/useLogin.ts。注册字段与校验注册表单包含三个字段username用户名、email邮箱、password密码。服务端registerUserserver/src/services/authService.ts会依次校验三字段非空密码满足强度规则见下节邮箱格式合法EMAIL_REGEX用户名/邮箱未与已有账号冲突返回 409且客座账号is_guest不会阻塞真实注册。密码使用 bcrypt 成本因子 12 哈希后落库随后签发会话令牌并写入trek_sessionCookie。密码强度要求密码必须同时满足以下全部规则实现在 server/src/services/passwordPolicy.ts 的validatePassword最短8 个字符至少包含一个大写字母至少包含一个小写字母至少包含一个数字至少包含一个特殊字符非字母数字不得是常见弱密码内置 30 余条黑名单如password、12345678、qwerty123、admin123、letmein12、welcome1、passw0rd、changeme等server/src/services/passwordPolicy.ts不得由单一重复字符构成正则^(.)\1$拦截如aaaaaaaa。管理员提示可以关闭开放注册仅保留邀请链接方式见 wiki/Admin-Users-and-Invites.md。邀请链接流程管理员分享形如/login?inviteTOKEN的邀请链接后访问它会依次发生前端见 client/src/pages/login/useLogin.ts向GET /api/auth/invite/:token校验令牌该端点本身也受登录桶限流保护server/src/nest/auth/auth-public.controller.ts校验通过后登录页自动切换到注册模式注册请求携带该 token使本次注册计入邀请链接的使用次数上限invite_tokens.used_count递增server/src/services/authService.ts。若令牌无效、过期或用尽页面会展示错误提示login.invalidInviteLink。另外若邀请链接绑定到具体行程trip-bound invite新注册用户会被自动加入该行程server/src/services/authService.ts。首个用户自动成为管理员在没有任何账号的全新 TREK 实例上注册表单会直接打开。服务端通过统计非客座用户数量判断isFirstUser首个账号的role被强制设为adminserver/src/services/authService.ts后续注册的账号默认均为普通user角色。按 IP 限流机制四类限流阈值TREK 对认证接口实施内存级的按 IP 限流同一 IP 在 15 分钟窗口内的允许次数如下操作阈值每 IP / 15 分钟对应桶登录失败/登录尝试含注册、邀请校验10 次loginMFA 验证尝试5 次mfa忘记密码请求3 次forgot重置密码提交5 次reset超过阈值后后续请求返回HTTP 429直到窗口重置。限流桶定义见 server/src/nest/auth/auth-public.controller.ts 的WINDOW 15 * 60 * 1000以及各端点调用处。底层实现限流核心是 server/src/nest/auth/rate-limit.service.ts 的RateLimitService一个内存中的双层 Mapbuckets → key(IP) → { count, first }check方法在count max且距首次尝试未超过窗口时拒绝请求server/src/nest/auth/rate-limit.service.ts。实现要点按命名桶隔离登录、MFA、忘记密码、重置密码互不干扰滑动窗口语义窗口内第 N1 次尝试立即被拒窗口过期后自动视为全新尝试纯内存实现服务重启后计数清零同一实例的 API 网关已通过插件宿主实现自身的限流见 server/src/nest/plugins/host/rate-limit.ts。此外登录接口还引入了最小响应延迟 350msLOGIN_MIN_LATENCY_MSserver/src/nest/auth/auth-public.controller.ts即使密码错误也会补足耗时配合“未知邮箱同样执行 bcrypt 假哈希”的策略server/src/services/authService.ts从时间维度进一步防御账号枚举与暴力破解。Demo 模式服务器以DEMO_MODEtrue启动时生产环境开启会打印安全警告见 server/src/index.ts登录表单下方会出现“Try demo”一键登录按钮。点击后调用POST /api/auth/demo-loginserver/src/nest/auth/auth-public.controller.ts免密直接以演示用户身份登录前端随后播放一段“飞机起飞”过渡动画并进入仪表盘client/src/pages/login/useLogin.ts。演示凭据demotrek.app/demo12345会随/api/auth/app-config返回demo_email/demo_password字段server/src/services/authService.ts但一键按钮才是官方推荐的进入方式。需要注意Demo 模式下注册被强制关闭password_registration: false且演示账号在许多业务接口上受到只读/受限处理server/src/middleware/auth.ts。SSOOpenID Connect登录常规 OIDC 登录管理员配置好 OpenID Connect 后登录表单下方会出现“Sign in with SSO”按钮按钮文案取自OIDC_DISPLAY_NAME环境变量默认回退到SSOserver/src/services/oidcService.ts。点击后前端跳转/api/auth/oidc/login服务端将浏览器重定向到身份提供方回调带回oidc_code后由前端完成 code 交换并恢复会话client/src/pages/login/useLogin.ts。OIDC-only 模式当实例处于OIDC-only 模式密码登录被禁用时访问/login会自动重定向到身份提供方不再展示邮箱/密码表单唯一的例外是你刚刚显式登出此时自动跳转被抑制改为展示 SSO 按钮让你主动选择重新登录client/src/pages/login/useLogin.ts 与 client/src/pages/LoginPage.tsx。OIDC-only 可由环境变量OIDC_ONLYtrue或数据库设置oidc_only触发app-config中的env_override_oidc_only字段会标明其来源server/src/services/authService.ts。完整配置与登录流说明见 wiki/OIDC-SSO.md。常见问题速查现象原因与解法明文 HTTP 下登录后下一请求 401SecureCookie 被浏览器丢弃。改用 HTTPS或开发环境设COOKIE_SECUREfalse登录被 429 拒绝同一 IP 15 分钟内登录尝试超过 10 次等待窗口重置会话提前失效检查SESSION_DURATION/SESSION_DURATION_REMEMBER是否被修改以及管理员是否执行了 JWT 轮换见 server/src/config.ts 的updateJwtSecret注册表单不显示实例关闭了开放注册且无有效邀请链接若为全新实例请确认has_users为 false相关文档wiki/Password-Reset.md · wiki/OIDC-SSO.md · wiki/Admin-Users-and-Invites.md · wiki/Two-Factor-Authentication.md【免费下载链接】TREKA self-hosted travel/trip planner with real-time collaboration, interactive maps, PWA support, SSO, budgets, packing lists, and more.项目地址: https://gitcode.com/GitHub_Trending/nomad22/TREK创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表