切换日光/暗黑模式
053. 用户注册与账号激活
学习目标
这一节实现注册接口和账号激活接口。
学完后,你应该能理解:
- 注册接口需要校验哪些内容;
- 为什么要检查用户名和邮箱是否重复;
- 密码强度校验应该返回什么;
- 未激活用户为什么不能直接登录;
- 激活 token 如何绑定用户名;
- 为什么真实项目不会把激活链接直接返回给前端。
注册接口参数
注册接口接收用户提交的信息。
常见字段包括:
- 用户名;
- 邮箱;
- 密码;
- 昵称或其他展示信息。
这些字段会通过注册参数结构进行约束。
后端不应该直接相信前端传来的数据。
密码强度校验
注册时要先检查密码强度。
密码强度工具可以返回两个值:
- 是否通过;
- 不通过时的错误信息。
如果密码太短,或者缺少大写字母、小写字母、数字等要求,就返回 400 Bad Request。
这类错误属于请求参数不符合要求。
用户名和邮箱不能重复
注册前要查询用户表。
如果用户名已经存在,不能继续注册。
如果邮箱已经存在,也不能继续注册。
用户名和邮箱通常都是登录、找回密码、通知用户的重要身份字段。
重复会让后续认证流程变得混乱。
创建用户
注册通过后,后端会创建用户记录。
创建时要注意:
- 密码要保存哈希值;
- 用户状态默认是未激活;
- 创建时间、更新时间等基础字段要写入;
- 数据库事务要提交。
如果忘记提交事务,接口看起来执行了,但数据库里不会有新用户。
这类问题适合用接口测试捕捉。
激活 token
注册后会生成一个激活账号用的 token。
payload 里至少包含:
- 用户名;
- token 类型;
- 过期时间。
token 类型用于区分它是激活账号使用,而不是 access token 或 refresh token。
激活链接
真实业务里,激活链接通常会发送到用户邮箱。
用户打开邮件里的链接后,浏览器访问后端激活接口。
课程项目没有企业邮件服务条件,所以注册接口直接返回激活链接,方便把流程跑通。
这个设计只适合学习和本地调试。
线上项目不应该把完整激活链接直接暴露在注册返回里。
激活接口
激活接口从查询参数里接收 token。
后端会做这些事情:
- 解码 token;
- 判断 token 是否有效;
- 从 payload 里拿到用户名;
- 查询对应用户;
- 把用户状态改为已激活;
- 提交数据库更新;
- 跳转到前端登录页。
如果 token 无效或过期,就返回错误。
并发更新保护
激活接口查询用户时,可以使用行锁。
它的作用是避免并发请求同时更新同一条用户记录。
这一节先使用这种写法,后面再系统讲悲观锁、乐观锁、原子更新和分布式锁。
先记住一点:当多个请求可能同时改同一条数据时,要考虑并发更新问题。
前端登录页跳转
激活成功后,后端可以把浏览器重定向到前端登录页。
用户看到登录页后,再输入用户名和密码登录。
这样注册、激活、登录就形成完整闭环。
激活链接泄露的边界
如果激活邮件被转发,别人点开链接也可能激活账号。
这是激活链接机制本身的特点。
但激活账号不等于登录账号。
真正敏感的是登录凭证、邮箱权限和后续 token。
真实项目要通过邮箱安全、链接过期时间和异常行为检测来降低风险。
这一节的重点
这一节把注册和激活串起来。
你需要记住:
- 注册前要校验密码强度;
- 用户名和邮箱不能重复;
- 新用户默认未激活;
- 激活 token 要有类型和过期时间;
- 学习项目可以返回激活链接,真实项目应该发邮件。