登录模块
相关技术:微信登录、短信、自定义注解、aop、策略模式、分布式事务
我们的单点登录是有状态登录,并且有多种登录方式,所以结合了策略模式,定义了抽象策略类,并提供了具体策略实现包括:
- 账户登录:用户名和密码
- 微信登录:openId
- 手机验证码:短信
我们还使用了分布式事务:例如微信登录时,如果用户已存在则直接登录,否则还要隐式去注册用户并初始化账户信息,由于用户和账户是两个服务。
分布式事务理论、分布式事务解决方案、seata相关理论
登录方式
手机验证码
前端就会验证手机号是否合法,如果合法,点击发送验证码,后台获取手机号:
- 验证手机号是否合法
- 查询redis中是否已发送过,如果已发送过则抛出异常,提示已发送
- 查询发送频率,如果发送频率超过xxx值,则抛出异常,提示发送太频繁
- 生成短信验证码,以手机号作为key,以code作为value,缓存到redis同时设置过期时间
- 调用阿里的短信接口,发送短信给用户
用户获取手机验证码之后,可以输入验证码,点击登录按钮,后台可以获取手机号及验证码:
- 验证手机号的合法性
- 根据手机号作为key到redis中查询验证码,和用户输入的验证码进行比较,如果不一致则抛出异常,提示验证码错误
- 根据手机号到mysql中进行用户查询,如果为空,则说明用户第一次用手机号登录,则隐式注册用户
- 通过uuid生成token,以token作为key,以用户作为value缓存到redis中
- 响应token给前端,保存到localStorage中
微信登录
前端会生成code,并把code提交到后台:
- 调用微信的远程接口:需要传递code、appid、secretkey给微信服务器
- 微信服务响应openId和sessionKey,咱们使用openId作为用户的唯一标识
- 根据这个唯一标识查询mysql的用户表,判断该用户是否已注册过,如果未注册则隐式注册用户
- 如果已注册,或者隐式注册成功,则通过uuid生成token
- 以token作为key 以用户信息作为value缓存到redis中
- 响应token给前端,保存到localStorage中
账号密码
账户登录:用户名和密码
前端用户输入用户名和密码之后,我们可以获取这些参数,在后台:
- 根据用户名查询用户
- 判断用户是否为空,如果为空则抛出异常,提示用户名或者密码错误
- 如果不为空,则对用户输入的密码进行加盐加密,然后和数据库查询的用户密码进行比较
- 如果不一致则说明密码错误,抛出异常提示用户名或者密码错误
- 如果一致则说明用户名和密码都正确了
- 通过uuid生成token信息,并把token和用户作为k和v缓存到redis中
- 把token返回给前端,保存在localStorage中
身份认证的流程
@GuiguLogin注解的作用
1.验证用户是否登录
2.获取用户信息
其他的实现方式
Gateway网关实现全局过滤器
项目采用自定义注解、AOP方式实现登录控制,我们只需要在需要登录的接口添加此注解即可。
具体开发步骤
有些接口需要登录才能使用,需要通过token获取登录信息并验证是否登录,为了通用我们使用了自定义注解 +
AOP封装了登录注解。
- 自定义了登录注解@Login
- 通过环绕通知针对注解进行了赋能
- 在环绕通知中获取请求对象的token:controller很好获取,通过RequestContextHolder对象在通知方法中获取request对象
- 通过token获取redis中的登录信息
- 如果登录信息为空则抛出异常
- 如果登录信息不为空则把登录信息(userId和userName)放入threadLocal 传递给后续Service
- 业务处理完成之后要释放ThreadLocal防止内存泄漏
介绍ThreadLocal对象
https://blog.csdn.net/u010445301/article/details/111322569
修改用户信息
具体流程
- 前端点击修改进行数据回显
- 前端将修改的数据提交
- 后台接收到数据进行更新操作
其他问题
小程序上登录了,在app上也登陆了,并且添加了收藏,小程序能不能看到
能看到。不管任何平台(小程序、ios、andriod、web),最终token对应的用户是同一个所以一端添加收藏另 一端是可以看到了
能不能多端同时登录?如何做到多端不能同时登录?怎么踢掉其他端登录状态
可以多端同时登录:一个用户在多端可能同时存在多个token。
token被盗了怎么办?
在登录信息中添加登录用户的ip。将来每次身份认证时获取请求用户id,两个ip进行比较,如果不一致说明是盗用的,则抛出异常跳转到登录页面。
生成一个随机盐。jwt(有效载荷 userId IP)
所有方案都无法防止100%盗用,只能尽量解决。