这节我们继续Go项目的实战开发,首先再看一下项目要实现的功能的用例图:
图片
图中用户认证相关的功能我们已经开发完了,在前面的四节课中详细地记述了他们的设计和开发过程,这一节我们行进到功能用例的第二大部分--用户个人信息管理。
前面两节我们还埋下了一个扣,说用户在修改密码后需要把用户在所有登录平台上的Token和Session全部清除掉,强制用户在每个平台上用新密码重新登录,这也是一项安全措施。那么这一节我们就先来开发用户密码的修改/重置,
重置密码的流程拆解和安全防护
用户在登录态下修改和重置密码比较好实现,很多产品的逻辑是登录情况下输入原密码、新密码就可以修改,而用户在无登录状态下做上面这些操作即找回密码的功能则需要通过让用户填写服务器发送给他们的验证码,进行确认后才能为用户修改密码。
我们这里就直接分析重置密码的功能吧,这个功能在逻辑实现上更完善一些,拿来做修改密码功能也能用。
重置密码的整个流程中服务端内部做了什么,和客户端怎么交互的,我用一张顺序图给大家做了梳理。大家先看一下:
图片
每个产品重置用户密码的功能实现跟这里说的可能有细微差别,但总体流程应该差不多。
- 客户端首先发起申请重置密码的请求,请求中需要提交它的邮箱/手机号
- 服务端验证用户是否存在、是否为正常状态,然后生成重置密码的Token和六位验证码
以Token为Key,将用户的ID和验证码存储到Redis,用于后续重置密码时的安全验证,缓存设置一个较短的有效期,比如半小时过期
通过邮件/短信的形式把验证码发送给用户
返回重置密码的Token给客户端
- 重置密码操作:客户端提交用户输入的新密码和验证码,头部携带Token发起发起请求
- 服务端验证信息后,把用户密码设置为新密码,然后把用户在Redis中保存的Session清空,强制把用户的登录状态踢掉。
这里注意一点,因为咱们的Token体系是支持多登录平台的,这里重置完密码后我们需要拿到用户在所有平台上的Token和Session信息都清掉,强制用户重新登录。
服务端把申请密码重置时缓存的验证码Code和重置Token删掉,防止用户的重复请求和恶意用户。
通过上面顺序图中客户端与服务端交互的会话框,我们可以看到密码重置功能需要两个接口来完成:
- 申请重置密码
- 提交重置密码
那么接下来我带大家一起写一下这两个接口,用代码实现我们在上面UML顺序图中整理出来的逻辑。
首先我们来看申请重置密码接口。
申请重置密码
申请重置密码功能,第三方对接应该是一些邮件或者是SMS短信服务,这个需要企业服务,就直接Mock掉了,大家真正在公司里开发项目时,记住与邮件对接的逻辑要写到Library里。
在开始写代码前我们再默念一遍逻辑分层的口诀
请求验证和数据绑定逻辑 --- Controller
外围业务逻辑 --- 应用服务
核心业务逻辑 --- 领域服务
数据访问逻辑 --- 数据访问层
第三方对接 -- Library(这个本节暂时用不到)
申请重置密码时,我们在下发重置密码的Token和验证码前需要在Redis缓存一份,用于后面用户提交重置密码时的验证,所以我们先从DAL层的代码开始。