骡窝窝02——短信验证码、用户登陆
短信验证码:
需求分析:
获取手机号码;前端
生成验证码;java
发送短信;web
短信验证码存储;面试
设计
verify_code : pahone
;value就是验证码,同时设置key的有效时机5分钟;spring获取手机号码与验证码code;数据库
将手机号拼接成key:
verify_code : pahone
,经过key去取值;编程对比验证码code与以前存的验证码;小程序
将取到的值和用户输入的验证码作对比。后端
问题点:
api
第一次请求存数据;
第二次请求要取数据;
须要作到请求之间的数据共享:
cookie:客户端技术,数据存在浏览器;主要弊端:安全性不高;
session:服务端技术,数据存在服务端是可行的,可是:
操做复杂须要存储数据较多(倒计时等操做不方便);
若是是先后端分离项目,建议不要用session;由于session在扩展小程序、移动端等开发时存在感不强(不符合通用编程);
Redis:Redis的特色:缓存数据库,易控制失效时间;
延伸:MySQL、MongoDB也能够实现验证码的存储,可是没法自动进行有效时间的控制,须要额外的代码加以控制;
Redis能够知足多个请求间的数据共享;
Redis自己就是临时数据存储数据库,天生支持数据时效性,验证码恰好须要这个特色;
Redis中k-v
对该怎么设计:
将他们简化成一个Map,在思考map中应该存什么样的k-v
对;
key怎么设计?(惟一性、可读性、时效性、灵活)
单独用手机号作key是可行的,可是可读性很差——加上前缀可读性更好;
时效性可直接设置key的失效时间;
value怎么设计(灵活)?
根据value的特色设计便可;
页面的倒计时:
前端代码:
表现层:
业务层:
将验证码存到Redis中:
先添加依赖,添加到哪?共用放core;
Redis的配置:不放在core中,由于有可能被覆盖,直接对子项目作配置便可;
core建立Redis文件夹统一管理Redis相关;
业务层:
建立方法:
实现:
完成k-v的存储和时间设置:
测试:
405:请求方式不匹配;
去Redis中查看数据是否存储完成;
验证过程;
测试:
从新发送短信验证码以后原来的值被覆盖了;因此要控制发送验证码的频率;
拓展:控制发送验证码的频率
思路:在Redis中存发送次数的限制,还有时效性,key为3,发一次减1,在发送短信以前判断一下key是否知足发送条件;
真实短信发送:
短信发送原理:
本身的短信发送:
企业的发短信:
短信网关:京东万象:https://wx.jdcloud.com/api-66
怎么用别人的接口来发短信:
须要借助短信网关的API:发起HTTP请求
//https://way.jd.com/chuangxin/dxjk?mobile=18487143792&content=【创信】你的验证码是:5873,3分钟内有效!&appkey=87f7d7e66d93f1022d52dfecf6e704ae
怎么发起http请求:RestTemplate
类。springmvc提供用于专门发起http请求的操做类;
多项目结构千万别按提示导入项目导入依赖:
导入依赖:
代码:
数据写死的配置,改源代码很差,路径放到配置文件中application.properties;
如何用到路径等配置:
表现层:
业务层:
技术延伸:
短信发送实际上也是项目之间的交互。要知道之后查询天气、身份核验等等公共的接口实现,也是项目之间的操做,要举一反三。(若是别人提供的项目的API,咱们就能够经过交互的方式来利用他的功能来实现本身的目的);
http和https他们的区别:
区别是https加密了;
数据加密传输,是HTTP和HTTPS之间的本质性区别。
锻炼本身面试时项目经验的表达能力:
口述:需求分析的过程,功能是怎么实现的,要注意哪一些细节,口述代码思路和流程思路;
细节优化
_class属性排除
Redis存储的时候,多出来的_class属性;
配置类中拷贝一个添加一个配置:
将数据库中的class数据删除掉,再添加就不会有class属性了;
统一异常处理
为何要统一异常处理(AOP [动态代理] )?
自定义异常的处理中代码出现重复了。如何减小重复:
模板方法:抽取的业务方法没办法统一块儿来;因此能够但不合适;
最佳实践:面向切面编程(AOP),在不改变业务代码的前提下,经过动态代理的方式对代码功能的加强;
代码实现:
在api子项目中建立包,专门管理advice加强类;
各类不一样的异常,怎么区分开来作处理:@ExceptionHandler
明确标记方法可处理哪一种类型的异常;
加强处理器中的方法与请求映射的方法设计同样,共享数据用model,参数接收用形参;
此时可能会出现异常的代码变成了这样:
Redis key重设计
枚举类:
java枚举类的用法一:常量,使用java枚举类能够替代常量,由于常量没有命名空间,使用起来不是很是清晰,若是使用java枚举类,就能够清晰地读懂代码,代码可维护性强
这样的代码中的常量怎么优化?
常量类统一管理的方式:
使用枚举类来管理常量:(枚举中常量不容许重复和key不重复天生一对)
key 须要灵活:如何改造?
面试点:
在代码中的应用:用枚举类来管理Redis的key
用户登陆:
需求分析:
获取参数用户名和密码;
经过数据库查询用户对象;
根据用户对象是否存在判断是否已经登陆;
须要将用户信息进行缓存,目的是下一次访问时,经过这个信息进行登陆判断;
登陆判断:
获取登陆的令牌和参数
经过令牌获取以前缓存起来的用户信息
用户信息数据存在哪里?
Session
:之前的方式,将用户的信息存在session中。原理:Session
的存储依赖于cookie
,Cookie
负责存Session
中的jSessionId
,session
中的用户数据存在服务端;Cookie
里的jSessionId
在浏览器,用户再次请求的时候,经过request
对象获取到Cookie
而后拿到jSessionId
,再经过jSessionId
去Session
中查询用户的信息,根据查询结果判断是否登录过;弊端:禁用cookie后将没法验证须要经过另外的方式处理,麻烦,数据量大服务器的性能降低;
Redis
数据库存储:(最佳实践)快,而且方便控制超时时间;经过UUID建立出一个随机的 登陆令牌,String token = 随机码;将token的随机码做为Redis的key,user对象做为value,存在Redis中;
返回token随机码到客户端;注意客户端须要将token保存起来;
客户端下一次访问时,经过http请求头的方式将token传到后台;
后台验证时,经过request对象获取到请求头,拿到token随机码;再用token随机码做为key查询Redis中的用户是否存在,判断用户是否已经登陆过;
用户登陆流程分析:
代码实现:
明白请求的访问地址和类型和参数:
表现层:
业务层:
持久层:
业务层完善:
表现层:
将数据存到Redis中:
key的可读性:
将token传到客户端保存起来:
参数怎么设计,才能去前台回调函数的参数格式对应起来?
测试:查看参数是否传到了前台
小伙砸,欢迎再看分享给其余小伙伴!共同进步!
本文分享自微信公众号 - java学途(javaxty)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。