注册登陆
注册包括邮箱注册和手机号注册,两种注册方法业务都相同,只是激活方式不同
注册模块:
- 用户在页面输入邮箱/手机号,点击获取验证码,就会向后台发送post请求
- 后端接收到前端请求,发送验证码
- 通过’工具类‘,生成一个随机四位数作为验证码
- 将验证码保存到**‘redis‘**中,redis保存数据是通过键值对的方式保存
- 所以我们可以通过电话+一个固定的常量作为key值
- 随机数+当前毫秒值作为value值
- 注意设置有效期,一般为5分钟
- 注意当用户点击获取验证码时,我们要判断用户是否已经点击过获取验证码
- 通过输入的手机号,按照我们拼接key值的方式拼接,然后从redis中获取
- 如果获取到的value值不为空,表示这不是第一次点击获取,此时我们需要判断当前时间和第一次点击获取的时间,如果小于一分钟,抛出异常,告诉用户不要重复获取验证码,如果超过了一分钟,此时我们的验证码还是等于第一次获取的验证码(这样做是为了防止网络问题导致验证码累计问题)
- 如果value值为空时,表明是第一次获取验证码,直接拼接验证码发送给用户
- 然后调用**‘发送验证码工具类‘**发送验证码给用户
- 用户在页面输入收到的验证码,点击注册
- 向后台发送请求,带有注册的信息
- 后端响应请求获取请求携带的参数,此时我们可以使用一个临时对象接受参数(方便定义添加属性)
- 首先第一件事就是进行校验
+ 校验数据是否为空,如果为空,抛出异常提示用户输入完整的信息
+ 校验手机号是否已被注册,通过前端传入的用户输入的手机号到数据库用户表进行查询,如果存在,抛出异常提示该手机已注册
+ 校验两次密码是否相同
+ 校验验证码,通过用户手机号和固定常量从redis中获取刚才发送的验证码
- 判断验证码是否为空,如果为空表示已过期,抛出异常告诉用户验证码过期,请重新获取验证码
- 如果不为空,比较用户输入的验证码和保存在redis缓存中的验证码是否相等,如果不等,抛出异常告诉用户验证码错误
- 校验成功之后,将临时对象转化为登陆信息对象,保存登陆信息对象,就有了id
注意我们在保存密码时为了安全性,需要对密码进行加密,我们是通过盐值进行加密
+ 通过随机数获取盐值,并保存到登录信息中
+ 加密方式MD5:输入任意长度的信息,经过处理,输出都是128位的信息值,无法看到明文
不同的输入对应的输出一定不同,保证唯一性
计算速度快,加密速度快
+ 调用\*\*[MD5工具类](#MD5)\*\*的方法使用密码+盐值进行加密并设置保存 **注意有顺序次数的问题**
+ 需要注意的是我们的登录信息包含前台普通用户和后台用户,为了区分,我们需要设置账户类型(0代表后台用户,1代表前台普通用户)
- 将登陆信息对象转化为user前端用户对象并保存,这样我们将关联了前端用户和登陆信息对象
+ (在转化对象时,相同普通属性进行拷贝,特殊属性手动设置)
- 没有问题就返回AjaxResult-success给前端
- 前端接收返回值,判断,如果注册成功,跳转到前端首页,如果不成功,就将错误异常展示到页面
账户密码(手机号,邮箱)登录模块
表的设计
用户是一张表,管理员是一张表,然后我们还做了一个登录表,登录表里面是所有用户和管理员的登录账号和密码,因为管理员也可以登录我们的网站享受服务,所以有可能一个手机或邮箱既是用户又是管理员。为了区分这种登录账号到底是要登录到后台还是网站,所以我们登录表里面有一个type字段,区分该账号到底是用户还是管理员
登录
- 当用户输入信息点击登录时发送post登录请求,并携带了登录信息
- 后台响应请求使用临时对象接收参数
- 校验登录信息
+ 校验数据是否完整
+ 校验用户名是否存在,通过用户输入的用户名查询登录信息表中的登录对象,判断是否为空
+ 密码是否正确 **注意此时校验密码我们需要将临时对象中的密码按照我们注册时的加密方式进行加密,然后与数据库保存的密码比对**
+ 还需要判断此用户对象对应的登录信息状态是否禁用
+ 返回对应的登录信息对象### 判断用户是否登录
后端
+ 校验登录信息正确之后,通过UUID产生随机的token值
+ 将token值和对应的的登录信息对象保存到redis内存中
+ 将token作为key,登录信息对象作为value,返回一个map给前端
### 前端
+ 登录成功,后端会返回map格式的token值,将token值保存到\*\*[localStorage](#storage)\*\*中
+ 跳转到前端首页### 判断登录
- axios前端前置拦截器:当前端每次发起请求时,都要将token值放入请求头中,每一个请求都需要token,所以我们可以配置一个前置拦截器,为所有请求头添加token
- 后端拦截器:后端接收前端的访问请求,判断有没有token,通过token查询数据库中是否有对应的登录信息
+ 如果没有,则没有登录,返回一个未登录的状态给前端,如果有就放行(注意配置拦截器拦截和放行的页面,比如注册和登陆的页面必须放行)
+ 如果有,返回true,同时再设置一次token有效期
- axios前端后置拦截器:判断后端拦截器返回的状态,如果为未登录状态,则跳转到登录页面,如果已登录状态,则跳转到请求访问的页面 **问题?**返回什么结果如何跳转到请求页面
微信第三方登陆
- 用户点击微信登陆时后端响应请求,拉取二维码,重定向到二维码展示界面
- 用户扫码确认登陆,执行回调函数并携带了授权码,我们设计了一个前端页面来响应这个回调函数,向后端发送请求获取登陆信息对象
- 后端响应请求,通过授权码获取用户的token信息地址url,我们**通过httpClient插件向token信息地址获取token和微信用户唯一标识**
- 通过token和唯一标识就能获取登录的微信用户的信息
- 我们通过微信中的唯一标识去微信用户表查询,如果存在就微信用户,继续判断是否有登陆信息,如果登陆信息不为空,直接登陆
- 如果没有登陆信息,就返回微信的用户的唯一标识,此时前端判断没有登陆信息只有唯一标识,跳转到绑定页面
- 如果有登陆信息,我们就创建token,放入redis中,并创建map放入token和登陆信息对象返回前端,前端判断有登陆信息,放入localstorage中,然后跳转到后台首页
相关工具代码
随机数工具类
1 | java复制代码package cn.itsource.pethome.basic.util; |
redis
了解数据库
数据库分类
- NoSQL非关系型数据库:存储数据都是没有结构的(没有表的概念),并且存储数据都是以key-value的的方式存储,都是把数据存储到内存或者磁盘上
- RDBSM关系型数据库:是有行和列组成的二维表,存储数据是有一定格式的,都是把数据存储到磁盘上
区别:
1. 关系型数据库不支持高并发访问,非关系型数据库支持高并发访问
2. 关系型数据库存储数据都是有结构的,而非关系型数据库存储数据是没有结构的(,没有表概念)
3. 关系型数据库存储数据只能放到磁盘上,非关系型数据库存储数据是放在内存和磁盘上
4. 关系型数据库的结构和数据存储都是有限的(列最多200列,存储数据量也是有限的,最多不超过200万),而非关系型数据库只要硬件够好,数据量是没有限制的
Redis是什么
Redis是一个高性能的开源的,c语言写的NoSQL,数据保存在内存/磁盘中。
Redis是以key-value形式存储,不一定遵循传统数据库的一些基本要求,比如不遵循sql标准,事务,表结构等,redis严格说来不是一个数据库,应该是一种数据结构化存储方法的集合
存储数据都是以字符串的形式进行存储,把存储的字符串按一定的规则进行摆放(规则:String list set zset Hash)
特点
- 开源免费
- 支持高并发,读取速度非常快
- 存储数据放到内存或者磁盘
- 支持多种类型的客户端访问(c,php,java)
- 支持集群(集群的意思:一台不够用就再加一台)
使用场景
- 做中央缓存
- 点赞计数器
- 防攻击系统
使用redis保存验证码
绿色版的在cmd终端启动服务 redis-server.exe redis.window.config
然后我们在springboot项目中使用redis
- 导包
1 | xml复制代码<!--对redis的支持--> |
- 配置文件application.properties
1 | properties复制代码# redis 属性配置 |
- 保存验证码到redis(我们为验证码设置对应的全局常量作为标识,并设置了当前的毫秒值,方便验证码过期问题)
1 | java复制代码 /package cn.itsource.pethome.basic.service.impl; |
手机发送验证码的包
1 | xml复制代码<!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient --> |
发送验证码的工具类
1 | java复制代码package cn.itsource.pethome.basic.util; |
发送邮件的配置
1 | properties复制代码# 设置邮箱主机(服务商) |
发送邮件的实现
1 | java复制代码package cn.itsource.pethome; |
MD5加密工具类
1 | java复制代码package cn.itsource.pethome.basic.util; |
storage的使用
1 | vue复制代码 <script type="text/javascript"> |
保存密码加密
1 | java复制代码package cn.itsource.pethome.user.service.impl; |
后端控制器
1 | java复制代码package cn.itsource.pethome.user.interceptor; |
axios前置后置拦截器
1 | js复制代码Vue.prototype.$http = axios; |
微信获取token的插件
1 | java复制代码package cn.itsource.pethome.basic.util; |
微信登陆的实现
1 | java复制代码package cn.itsource.pethome.user.service.impl; |
随机生成订单号
1 | java复制代码/** |
通过地址获取经纬度距离
1 | java复制代码package cn.itsource.pethome.basic.util; |
fastdfs上传下载文件
1 | java复制代码package cn.itsource.pethome.basic.util; |
常用包
1 | xml复制代码 <!--对redis的支持--> |
本文转载自: 掘金