总结
- 创建用户中心
- 了解面向接口开发方式
- 实现数据校验功能
- 实现短信发送功能
- 实现注册功能
- 实现根据用户名和密码查询用户功能
1.用户中心服务
- 用户注册 / 登录 / 个人信息管理 / 地址管理 / 收藏管理 / 我的订单 / 优惠券管理
- 其他微服务也会调用用户中心的服务,因此这里做聚合,即抽取出接口到interface
- leyou-user-interface:实体及接口
- leyou-user-service:业务和服务
1.1 数据校验功能
- 接口路径:GET /check/{data}/{type} data 要校验的数据; type 要校验的数据类型:1,用户名;2,手机;
- 返回结果:true:可用; false:不可用
- 根据data查出对应User对象;查询该对象的记录数 ==? 0
1.2 通知短信微服务发送短信功能
根据请求里的手机号,生成验证码,将验证码和手机号封装到Map<String, String> map中 — 并发送消息给消息队列的交换机 — 交换机根据路由分配给对应微服务 — 短信服务的队列绑定了交换机,指定了路由,可以接收到绑定交换机和指定路由的消息。
- 生成验证码
- 将生成验证码逻辑写在common微服务中的NumberUtils类中的generateCode(int len)。
- 发送验证码
- 将验证码和手机号封装到Map<String, String> map中,并发送消息给消息队列的交换机。
- 将验证码code存入redis中,设置短信验证码在Redis的缓存时间为5分钟?
为什么要将code存在redis中
- 获取用户输入的手机号后,再生成验证码,包装成Map<> msg发送给消息队列,通知发送短信微服务发送短信,将code保存在redis中,
- 用户收到短信中验证码后,填写到表单,提交注册表单,用户微服务提取表单里的用户信息和验证码,将发送回来的验证码和redis中的验证码比较,来确定用户是否会注册成功。
- 所以,通知发送短信前,将code保存在redis中,为了待会儿和提交的注册表单中的code进行比较,因为redis比较快;
1.3 注册功能
- 校验短信验证码
- 注册表单里的验证码和最初生成并发送出去,存储在redis中的验证码比较。
- 生成盐
- 工具类生成String类的盐
- 对密码加密
- 用户自定义的密码 + 盐 --(加密) – 存储在数据库
- 加密,主要是防止在传输的过程中被篡改
- 写入数据库
- 将User对象存储在数据库,并返回Boolean, 是否注册成功
- 删除Redis中的验证码
1.4 根据用户名和密码查询用户,即判断输入的用户名和密码是否有误功能
-
校验用户名
- 根据用户名生成的对象,用mapper查询到的条数是1, 证明用户名没有错,数据库中存在该用户
- 校验完用户名之后,得到了用户,即数据库中的用户数据后,再去根据数据里的数据校验密码(数据库中:该用户盐和加密后密码)
-
校验密码
- 传进来的密码和和数据库里该行存储的盐 —(加密算法) — 得到加密密码 — 和数据库中的加密密码比较 — 是否一致
- 一样就代表密码输入是对的,否则密码是错误的
2.阿里大于短信服务
- 因为系统不止注册一个地方需要短信发送,因此需要将短信发送抽取为微服务:leyou-sms-service
- 短信发送API调用时长不确定,为提高程序的响应速度,短信发送采用异步发送
- 短信服务监听MQ消息,收到消息后发送短信
- 其他服务要发送短信,向MQ发送一条消息,通知短信微服务
2.1发送短信功能
监听到消息,取出消息里的手机号和验证码 Map<String, String> key: “phone” , “code”, 发送短信。
- 按照文档,创建SmsProperties类,读取application.yml配置属性
- 按照文档,创建SmsUtils类
- sendSms(String phone, String code, String signName, String template)方法 发送短信
- SmsListener监听类
- listenSms(Map<String, String> msg)方法
- 命名存储消息的队列
- 绑定路由消息的交换机
- 执行路由 key = {“sms.verify.code”}
发短信单独作为一个微服务,因为的微服务需要发送短信这个功能。
提供接口,供别的微服务调用
- 耦合度高,如果接口逻辑改了,还要改自己的代码。
- 短信多长时间能够发送出去,也不知道,还要等着发送成功,自己才能响应成功。
谁要发送短信,谁就向消息队列发送消息,短信微服务去监听队列就可以了
微服务不需要eureka,只需要监听队列,发送消息,不需要调用别人的微服务,别的微服务也不会调用这个微服务,别的服务要发送短信,只需要向消息队列发送消息就可以。相当于一个工具微服务,
sms微服务监听消息队列,接收到消息后,便发送短息phoen , 验证码
其他微服务发送短信,手机号,验证码,
验证码还要保存在服务器端,将来看用户验证码是否输入正确。
- 放在session中,有可能服务器时分布式的,session不共享。有可能是一个服务器生成验证码,另一个服务器验证注册,另外一台服务器没有保存这个验证码,无法验证
- mysql, 两个列,一列是手机号,一列是短信验证码内容。根据手机号存,根据手机号取。但是短信验证码发送很多次,这张表可能有几十亿,几百亿条,很大。
- redis,因为验证码几分钟就无效了,性能高,设置过期时间。
用户注册register微服务需要发送短信
注册功能:
校验用户名是否被注册
发送短信验证码,让用户输入验证码,然后校验验证码是否正确
添加用户到mysql,完成注册
当验证用户输入的用户名没有被注册,就生成验证码,并将手机号一起,发送消息给消息队列。
form表单参数和问号后面的参数都是普通参数,如果分别接收,需要加requestParam; 用对象直接接收。
user对象里面没有短信验证码属性,
如果是传过来的是json数据,
除了前端要做校验外,后端也要做校验,例如用post工具直接发请求,跳过前端的校验
引入Herbinate依赖,在user类上的属性添加校验注解
校验注解怎么跟SpringMVC产生关联,
SpringMVC:提供注解驱动元素,在SpringMVC里要配置三个基本的,注解驱动,内部视图资源解析器,包扫描
SpringMVC支持JSR303,只要引入JSR303依赖,就去支持
根据用户名和密码查询用户,返回的用户不包括密码和盐
数据库的密码和传进来的密码是不一样的,所有不能直接用密码来查,应该先用用户名去查,得到对象,取对象的密码和salt,将传进来的密码和salt生成密码,校验这个密码和数据库的密码是否一致。
504网关问题