Java项目笔记之短信验证码、用户登陆


不点蓝字,咱们哪来故事?



骡窝窝02——短信验证码、用户登陆

短信验证码:

需求分析:

  1. 获取手机号码;前端

  2. 生成验证码;java

  3. 发送短信;web

  4. 短信验证码存储面试

    设计 verify_code : pahone;value就是验证码,同时设置key的有效时机5分钟;spring

  5. 获取手机号码与验证码code;数据库

    将手机号拼接成key:verify_code : pahone,经过key去取值;编程

  6. 对比验证码code与以前存的验证码;小程序

    将取到的值和用户输入的验证码作对比。后端

问题点
api

  • 第一次请求存数据;

  • 第二次请求要取数据;


须要作到请求之间的数据共享

  • cookie:客户端技术,数据存在浏览器;主要弊端:安全性不高

  • session:服务端技术,数据存在服务端是可行的,可是:

    • 操做复杂须要存储数据较多(倒计时等操做不方便);

    • 若是是先后端分离项目,建议不要用session;由于session在扩展小程序、移动端等开发时存在感不强(不符合通用编程);

  • Redis:Redis的特色:缓存数据库,易控制失效时间;

    延伸:MySQL、MongoDB也能够实现验证码的存储,可是没法自动进行有效时间的控制,须要额外的代码加以控制;

    • Redis能够知足多个请求间的数据共享;

    • Redis自己就是临时数据存储数据库,天生支持数据时效性,验证码恰好须要这个特色;


Redis中k-v对该怎么设计:

将他们简化成一个Map,在思考map中应该存什么样的k-v对;

  1. key怎么设计?(惟一性、可读性、时效性、灵活

    • 单独用手机号作key是可行的,可是可读性很差——加上前缀可读性更好

    • 时效性可直接设置key的失效时间;

  2. 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



用户登陆:

需求分析

  1. 获取参数用户名和密码;

  2. 经过数据库查询用户对象;

  3. 根据用户对象是否存在判断是否已经登陆;

  4. 须要将用户信息进行缓存,目的是下一次访问时,经过这个信息进行登陆判断;

  5. 登陆判断:

    • 获取登陆的令牌和参数

    • 经过令牌获取以前缓存起来的用户信息


用户信息数据存在哪里

  1. Session:之前的方式,将用户的信息存在session中。原理Session的存储依赖于cookieCookie负责存Session中的jSessionIdsession中的用户数据存在服务端;Cookie里的jSessionId在浏览器,用户再次请求的时候,经过request对象获取到Cookie而后拿到jSessionId,再经过jSessionIdSession中查询用户的信息,根据查询结果判断是否登录过;

    弊端:禁用cookie后将没法验证须要经过另外的方式处理,麻烦,数据量大服务器的性能降低;


  2. Redis数据库存储:(最佳实践)快,而且方便控制超时时间;



    • 经过UUID建立出一个随机的 登陆令牌,String token = 随机码;将token的随机码做为Redis的key,user对象做为value,存在Redis中;

    • 返回token随机码到客户端;注意客户端须要将token保存起来

    • 客户端下一次访问时,经过http请求头的方式将token传到后台

    • 后台验证时,经过request对象获取到请求头,拿到token随机码;再用token随机码做为key查询Redis中的用户是否存在,判断用户是否已经登陆过;


用户登陆流程分析:

代码实现:

明白请求的访问地址和类型和参数:

表现层:

业务层:

持久层:

业务层完善:

表现层:

将数据存到Redis中:

key的可读性:

将token传到客户端保存起来:


参数怎么设计,才能去前台回调函数的参数格式对应起来?

测试:查看参数是否传到了前台



java学途

只分享有用的Java技术资料 

扫描二维码关注公众号

 


笔记|学习资料|面试笔试题|经验分享 

若有任何需求或问题欢迎骚扰。微信号:JL2020aini

或扫描下方二维码添加小编微信

 




小伙砸,欢迎再看分享给其余小伙伴!共同进步!




本文分享自微信公众号 - java学途(javaxty)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索