目录

  • 1.内容
  • 2.用户站点搭建
    • 2.1.用户站点搭建
    • 2.2.创建工程
    • 2.3.相关组件集成
    • 2.4.基础代码生成
    • 2.5.表分析
    • 2.6.位状态
    • 2.7.生成代码
  • 3.门户-用户前端搭建
    • 3.1.搭建工程
      • 3.1.1.创建静态项目
      • 3.1.2.拷贝页面
    • 3.2.启动工程
  • 4.个人中心
    • 4.1.个人资料
    • 4.2.实名认证
      • 目前主流的实名认证方式:
      • 4.2.1.人工审核
      • 4.2.2.自动审核
      • 4.2.3.自动审核+人工
    • 4.3.我的收藏
    • 4.4.我的消息
  • 5.注册逻辑
    • 5.1. 注册分析
      • 5.1.1 注册流程
      • 5.1.2 注册需求
    • 5.2. 图片验证码
      • 5.2.1. 单体应用验证码方案
      • 5.2.2. 前后端分离验证码方案
      • 5.2.3. 图片验证码流程
      • 5.2.4. 图片验证码实现
        • 1.图片验证码前端
        • 2.图片验证码Controller
        • 3.图片验证码Service
        • 5.创建Redis设置值-超时时间设置
        • 6.用户服务依赖cache-feign
        • 7.开启Feign
        • 8.yml开启熔断
        • 9.修改图片验证码工具类
    • 5.3. 短信验证码
      • 5.3.1. 短信验证码方案思考
      • 5.3.2. 短信验证码流程分析
      • 5.3.3. 短信验证码实现
        • 1.按钮倒计时分析
        • 2.发送短信controller
        • 3.发送短信service
        • 4.封装Http工具
      • 5.3.4. 短信网关
        • 1) 短信发送原理
        • 2)短信网关注册
        • 3)发送短信
    • 5.4. 完成注册
      • 5.4.1 注册流程
      • 5.4.2 后台注册逻辑
      • 5.4.3 位状态处理
  • 6. 课程总结
    • 6.1.重点
    • 6.2难点
    • 6.3.课后作业
    • 6.4.面试题

1.内容

1. 用户站点搭建
2. 门户-用户前端搭建
3. 个人中心
4. 用户注册

2.用户站点搭建

2.1.用户站点搭建

2.2.创建工程

hrm-user-parenthrm-user-commonhrm-user-server-1090

2.3.相关组件集成

2.4.基础代码生成

2.5.表分析

2.6.位状态

2.7.生成代码

3.门户-用户前端搭建

3.1.搭建工程

3.1.1.创建静态项目
Hrm-website-parentHrm-website-user
3.1.2.拷贝页面

拷贝准备好的页面到项目中

3.2.启动工程

live-server --port=6003

4.个人中心

4.1.个人资料

前端填写个人资料信息,提交保存,后台需要创建个人资料保存接口,将数据存储到数据库,这个只是一个简单的保存/修改操作

4.2.实名认证

目前主流的实名认证方式:

1.身份证+姓名认证 —安全级别最低
2.通过第三方实名 (通过支付宝认证或微信认证)—第三方微信登录
3.填写身份证号+上传身份证正反面(阿里云平台中也有相应的接口提供)
4.人体活脸识别(摇头、点头、向左转脸)— 建议使用阿里云

4.2.1.人工审核

实名认证表RealAuth中记录实名认证申请信息,应该有3种状态,前端提交实名认证申请,保存信息到RealAuth表中,状态为 “申请中”,后台管理系统读取申请中的实名信息进行审核,审核人员可以点击“审核通过”,和“审核失败”两个按钮取修改数据库中的实名申请记录的状态为“通过”,或者“拒绝”,如果拒绝,用户需要在前端重新发起实名申请。

4.2.2.自动审核

上面这种审核方式是人工审核,可能并不能有效的审核出审核信息的真实性,通常情况下我们可以加上“三方实名接口”进行自动审核。

用户前端提交实名申请是,带着姓名和身份证号码以及身份证图片调用三方实名认证接口,三方实名认证接口会校验身份信息的真实性,返回实名认证结果成功或者失败。平台可以根据句这个结果直接决定实名认证审核通过,或者不通过,只需要将实名认证表RealAuth中的状态修改成对应的状态即可

4.2.3.自动审核+人工

在一些对实名信息的真实性要求比较高的应用中(比如贷款平台),可能会采取自动审核+人工审核方式,及自动审核通过只是作为一审,后台工作人员会第二次审核实名信息(比如通过电话方式询问你的实名信息或者询问你的家人进行核实) , 有的平台还会通过和申请人面对面开视频的方式来核实用户的真实信息。

4.3.我的收藏

这个功能很简单,当用户在前端点击 “收藏课程”,我们只需要把用户的ID和课程的ID保存数据库即可,在个人中心,我的收藏列表中根据登录用户查询对应的收藏信息即可。

4.4.我的消息

当用户做了某些操作,比如 充值 ,购买了课程之后,系统默认发送一条消息给用户,这个功能只需要把消息保存到数据库中,然后对用好用户的ID,表明这个消息是发送给哪个用户的,然后在用户的个人中心根据用户的登录的ID查询消息列表中的数据即可。

5.注册逻辑

5.1. 注册分析

5.1.1 注册流程

5.1.2 注册需求

页面参数基本验证
图片验证码使用Ajax异步请求获取
图片验证码的自使用Redis进行存储,并且不允许产生大量的无效图片验证码
图片验证码需要设计过期时间10分钟

发送手机验证码按钮倒计时效果(60S后重发)
发送手机验证码发送频繁判断(两次发送时间间隔要大于60S)
发送手机验证码需要验证码图片验证码是否正确或是否过期
发送手机验证码时如果上一次发送了一个验证码未使用并且有效,那么使用上一次的验证码再发送一次,并做过期时间重置

注册需要做基本参数判断,比如空值
注册需要判断手机号是否已经被注册
注册需要判断注册提交的手机号和接受验证码的手机号是否一致
注册需要判断手机验证码是否正或者是否过期

5.2. 图片验证码

5.2.1. 单体应用验证码方案

前端的图片验证码一般是后台返回的一个base64格式的字符串

1.前端发送图片验证码获取请求
2.后端收到请求,生成图片验证码的值
3.把图片验证码的值存储到Session
4.把图片验证码的值合并到一个图片中
5.通过Response把图片使用流的方式响应给前端
6.前端展示图片,用户输入图片验证码的值
7.前台提交注册请求 ,验证图片验证码,后端把前端传入的图片验证码的值和Session中的图片验证码的值做比较

5.2.2. 前后端分离验证码方案

思考问题

现在还能用Response把图片响应给标签吗 , 不能,因为我们前端使用Ajax发请求了?怎么响应:把图片基于Base64编码,把编码后的字符串响应给前端,一样的能展示
还能用session存储图片验证码的值吗?不能,我们使用Redis存储图片验证码
图片验证码在Redis的key如何生成?(需求:不准出现大量无用的key在Redis,多个页面的图片验证码也不能覆盖)

即:不管什么情况,只要打开一个注册页面,那么就应该有一个唯一的KEY,及时多个人 打开多个注册页面,也是不同的key

同一个电脑,同一个浏览器, 同一个页面 ,多次获取图片验证码,使用同一个key

我们在前端使用UUID来生成后端Redis的key,同一个页面使用唯一的一个KEY。

解决方案

5.2.3. 图片验证码流程

1.请求图片验证码之前判断SessionStorage是否有KEY,如果没就创建,然后保存SessionStorage,如果有自己直接作为参数发送Ajax请求获取图片验证码
2.前端通过ajax发送一个图片验证码请求,携带者KEY
3.后端收到请求,生成图片验证码的值
4.把图片验证码的值存储到Redis,以前段传入的key作为Redis的key
5.把图片验证码的值合并到一个图片中
6.把图片基于Base64编码层字符串,响应给前端
7.前端拿到base64字符串,进行图片的展示,用户输入图片验证码
8.前台提交注册请求 ,验证图片验证码(key也要携带),后端把前端传入的图片验证码的值和Redis中的图片验证码的值做比较

5.2.4. 图片验证码实现
1.图片验证码前端

前段省略…

createUuid(){var s = [];var hexDigits = "0123456789abcdefghi";for (var i = 0; i < 36; i++) {s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);}s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01s[8] = s[13] = s[18] = s[23] = "-";var uuid = s.join("");return uuid;
},
getImageCode(){//发送请求到后台获取数据  VerifycodeControllerlet imageCodeKey = sessionStorage.getItem("registerImageCodeKey");if(!imageCodeKey || imageCodeKey === ''){imageCodeKey = "reg_"+this.createUuid();sessionStorage.setItem("registerImageCodeKey",imageCodeKey);}this.$http.get("/user/verifycode/imageCode/"+imageCodeKey).then(res=>{//res.data :就是base64编码后的图片的字符串this.imageCode = this.imageCodePrefix+res.data.resultObj;})
},
2.图片验证码Controller
//验证码相关
@RestController
@RequestMapping("/verifycode")
public class VerifycodeController {@Autowiredprivate IVerifyCodeService verifyCodeService ;@RequestMapping(value = "/imageCode/{key}",method = RequestMethod.GET)public AjaxResult createImageCode(@PathVariable String key){try{String baseImageStr = verifyCodeService.createImageCode(key);return AjaxResult.me().setResultObj(baseImageStr);}catch (Exception e){e.printStackTrace();return AjaxResult.me().setSuccess(false).setMessage(e.getMessage());}}
}
3.图片验证码Service
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {@Autowiredprivate CommonFeignClient commonFeignClient ;@Overridepublic String createImageCode(String key) {//1.判断key不为空if(StringUtils.isBlank(key)){throw new RuntimeException("无效的KEY");}//2.使用UUID生成一个图片验证码的值String imageCodeValue = UUID.randomUUID().toString().substring(0,4);//3.把验证码的值存储到Redis,以前台传入的key作为key ,设置过期时间commonFeignClient.setex(key,600,imageCodeValue);//4.把验证码的值合并到图片//5.把图片使用Base64编码//6.返回base64编码的字符串try {return VerifyCodeUtils.verifyCode(140,40,imageCodeValue);} catch (IOException e) {e.printStackTrace();throw new RuntimeException("图片验证码创建失败");}}
}

图片验证的第2种实现效果

第一步,导入图片验证码所需的依赖

<!-- 图片验证码所需依赖-->
<dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version>
</dependency>

第二步:复制生成图片验证码的工具类

import com.wf.captcha.ArithmeticCaptcha;
import java.util.HashMap;
import java.util.Map;/*** 功能说明 算术运算验证码* @author caiwen* @date 2021/1/30*/
public class VerifyEasyCptchaUtils {/*** 功能说明 获取数字运算的相关参数(base64图片+运算结果)对象* @param width     生成的图片宽度* @param heigh     生成的图片高度* @param numLength 几位数的运算* @return Map<String, String>。有2个key,resultData:运算结果;imgBase64:base64的转码图片* @author caiwen* @date 2021/1/30*/public static Map<String, String> getImageEasyCaptcha(int width, int heigh, int numLength) {// 算术类型 https://gitee.com/whvse/EasyCaptchaArithmeticCaptcha captcha = new ArithmeticCaptcha(width, heigh);// 几位数运算,默认是两位captcha.setLen(numLength);HashMap<String, String> map = new HashMap<>();try {map.put("resultData", new Double(Double.parseDouble(captcha.text())).intValue() + "");} catch (Exception e) {map.put("resultData", captcha.text());}map.put("img", captcha.toBase64());return map;}
}

第3步:在需要生成图片验证码的地方,调用方法生成验证图片
//参数1:表示生成验证码图片的宽度;参数2:生成图片的高度;参数3:运算表达式的计算范围。
Eg:2表示是2位数的运算

Map<String, String> imageEasyCaptcha = VerifyEasyCptchaUtils.getImageEasyCaptcha(111, 36, 2);

第4步:返回的map类型的结果,包含2个值:

Key=resultData  这是运行结果
Key=img  这是base64格式的图片

课外作业:

要求:将系统中用于缓存操作的2个工具对象:redis 和 spring-cache封装到 一个新的服务
Hrm-cache-parent中,然后以Feign接口的方式,提供给其他的微服务使用
5.创建Redis设置值-超时时间设置

1.修改RedisUtils

public void set(String key,int seconds, String value) {Jedis jedis = getSource();jedis.setex(key,seconds, value);closeSource(jedis);
}

2.编写RedisController

@RequestMapping(value = "/setex",method = RequestMethod.POST)
public AjaxResult setex(@RequestParam("key") String key  ,@RequestParam("seconds")int seconds,@RequestParam("value")String value){RedisUtils.INSTANCE.set(key,seconds,value);return AjaxResult.me();
}

3.编写Feign接口

@RequestMapping(value = "/redis/setex",method = RequestMethod.POST)
AjaxResult setex(@RequestParam("key") String key  ,@RequestParam("seconds")int seconds,@RequestParam("value")String value);

编写Feign接口降级

6.用户服务依赖cache-feign
<dependency><groupId>cn.itsource.hrm</groupId><artifactId>hrm-cache-feign</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
7.开启Feign
//系统管理服务
@SpringBootApplication
@EnableDiscoveryClient //服务发现客户端
@EnableFeignClients
public class UserApplication1090
{public static void main( String[] args ){SpringApplication.run(UserApplication1090.class) ;}
}
8.yml开启熔断
feign:hystrix:enabled: true
9.修改图片验证码工具类
public static String verifyCode(int w, int h, String code) throws IOException {//base64编码工具BASE64Encoder encoder = new BASE64Encoder();//用来装图片的ByteArrayOutputStream data = new ByteArrayOutputStream();//把验证码合并到图片,把图片转到 data里面outputImage(w, h, data, code);//base64编码图片,并返回return encoder.encode(data.toByteArray());
}

5.3. 短信验证码

5.3.1. 短信验证码方案思考

1.短信验证码的大致流程?
2.按钮倒计时效果如何实现?
3.短信验证码后台如何存储?Redis
4.如果使用Redis存储,Redis的key如何创建?不同的页面的短信验证码的key不能覆盖

5.3.2. 短信验证码流程分析


1.前台发起验证码发送申请(Ajax),并且按钮倒计时、禁用
2.后台接收到请求,判断图片验证码是否合法
3.判断上一次是否有一个未使用的有效验证码
4.如果有,并且过了重发时间(两次发送时间大于60S)使用上一次有效验证码
5.如果没有,创建一个新的短信验证码
6.把短信验证码存储到Redis,格式如: SMS:18244229575={code:”1234” , sendTime: “mills”}
7.调用第三方短信网关发送短信验证码
8.DB存储验证码发送记录作为结算依据

5.3.3. 短信验证码实现
1.按钮倒计时分析
1)点击按钮,判断手机号,图片验证码不可为空
2)禁用按钮
3)发送Ajax请求发送短信 :参数?手机号,图片验证码的值,图片验证码的key
4)如果发送成功a.给出提示b.进入倒计时c.倒计时完成:重置按钮,清除倒计时
5)如果发送失败a.给出提示b.重置按钮
sendSmsCode(event){//1.判断手机号不为空if(!this.formParams.mobile){alert("手机号不能为空");return;}//2.判断图片验证码不为空if(!this.formParams.imageCode){alert("图片验证码不能为空");return;}//3.获取按钮,禁用按钮var sendBtn = $(event.target);sendBtn.attr("disabled",true);var param = {mobile: this.formParams.mobile,imageCode:this.formParams.imageCode,imageCodeKey:sessionStorage.getItem("registerImageCodeKey");  //"reg_xxxx"};//4.发送ajax请求this.$http.post("/user/verifycode/sendSmsCode",param).then(res=>{var ajaxResult = res.data;if(ajaxResult.success){alert("手机验证码已经发送到您的手机,请在10分钟内使用");//4.1.发送成:倒计时var time = 10;var interval = window.setInterval( function () {//每一条倒计时减一time = time - 1 ;//把倒计时时间搞到按钮上sendBtn.html(time+"秒后重发");//4.2.倒计时完成恢复按钮if(time <= 0){sendBtn.html("重新发送");sendBtn.attr("disabled",false);//清除定时器window.clearInterval(interval);}},1000);}else{//4.3.发送失败:提示,恢复按钮sendBtn.attr("disabled",false);alert("发送失败:"+ajaxResult.message);}})
}
2.发送短信controller
//发送手机验证码
@RequestMapping(value = "/sendSmsCode",method = RequestMethod.POST)
public AjaxResult sendSmsCode(@RequestBody SMSCodeDto smsCodeDto, HttpServletRequest request){verifyCodeService.sendSmsCode(smsCodeDto,request);return AjaxResult.me();
}
3.发送短信service

//1.参数判断
//2.判断图片验证码:
// 2.1.根据前段传入的key去Redis获取图片验证码的值,
// 2.2.传入的图片验证码的值和Redis中的值比较
//3.获取上一次短信验证码发送记录

//3.1.上一次有
//3.1.1.判断时候是否过了重发时间 :当前时间 - 上一次发送时间 > 60s
//3.1.2.如果没过重发时间 - 报错
//3.1.3.如果过了重发时间 ,获取上一次验证码的值

//3.2.上一次没有
//3.2.1.创建一个手机验证码

//4.把手机验证码发送记录存储到Redis
//5.调用短信网关发送手机验证码
//6.存储验证码的发送记录到Mysql

@Override
public void sendSmsCode(SMSCodeDto smsCodeDto, HttpServletRequest request) {String imageCode = smsCodeDto.getImageCode();String imageCodeKey = smsCodeDto.getImageCodeKey();String mobile = smsCodeDto.getMobile();//1.参数判断if(StringUtils.isBlank(mobile)){throw new GlobalException("手机号不可为空");}if(StringUtils.isBlank(imageCodeKey)){throw new GlobalException("请刷新页面重新获取图片验证码");}if(StringUtils.isBlank(imageCode)){throw new GlobalException("图片验证码不可以为空");}//2.判断图片验证码:// 2.1.根据前段传入的key去Redis获取图片验证码的值,AjaxResult ajaxResult = commonFeignClient.get(imageCodeKey);if(!ajaxResult.isSuccess() || ajaxResult.getResultObj() == null){throw new GlobalException("无效的图片验证码或过期,请重新输入");}// 2.2.传入的图片验证码的值和Redis中的值比较String imageCodeValue = ajaxResult.getResultObj().toString();if(!imageCodeValue.toLowerCase().equals(imageCode.toLowerCase())){throw new GlobalException("错误的图片验证码,请重新输入");}//当前时间Date now = new Date( );//3.获取上一次短信验证码发送记录//手机验证码的值  REG:PHONE:182xxxxxString SMSCodeKey = SMSCODE_IN_REDIS_KEY_PREFIX+mobile;AjaxResult getSMSCodeAjaxResult = commonFeignClient.get(SMSCodeKey);//手机验证码String SMSCodeValue = null;if(getSMSCodeAjaxResult.isSuccess() && getSMSCodeAjaxResult.getResultObj() != null){//3.1.上一次有SMSCodeSendVo lastSendVo = JSON.parseObject(getSMSCodeAjaxResult.getResultObj().toString(),SMSCodeSendVo.class);//3.1.1.判断时候是否过了重发时间 :当前时间 - 上一次发送时间 > 60sif( ((now.getTime() - lastSendVo.getSendTime().getTime())/1000 ) < 60){//3.1.2.如果没过重发时间 - 报错throw new GlobalException("发送频繁,请稍后重试");}//3.1.3.如果过了重发时间 ,获取上一次验证码的值SMSCodeValue = lastSendVo.getCode();}else{//3.2.上一次没有//3.2.1.创建一个手机验证码SMSCodeValue = StrUtils.getRandomString(4);}//4.把手机验证码发送记录存储到Redis//手机验证码发送记录JSON值String SMSCodeSendVoJson = JSON.toJSONString(new SMSCodeSendVo(SMSCodeValue,now));AjaxResult SMSCodeAjaxResult = commonFeignClient.setex(SMSCodeKey,600,SMSCodeSendVoJson);if(!SMSCodeAjaxResult.isSuccess()){//log.errorthrow new GlobalException("手机验证码发送失败");}//5.调用短信网关发送手机验证码String sendMessage = "亲爱的用户,您的手机验证码为【"+SMSCodeValue+"】,请在"+(10)+"分钟内使用";System.out.println(sendMessage);//短信网关地址String url = "http://utf8.api.smschinese.cn/";Map<String,String> map = new HashMap<>();map.put("Uid","wolfboy");map.put("Key","2d91c77b0522e51b7791");map.put("smsMob",mobile);map.put("smsText",sendMessage);//发送短信,处理结果WebchineseSMSResult.checkResult(HttpUtil.sendPost(url,map));//6.存储验证码的发送记录到Mysql(ip,手机号,验证码,发送时间,状态) :省略System.out.println(request.getRemoteAddr());
}
4.封装Http工具
<dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.4</version>
</dependency><dependency><groupId>commons-httpclient</groupId><artifactId>commons-httpclient</artifactId><version>3.1</version>
</dependency>
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;public class HttpUtil {public static String sendPost(String url, Map<String,String> params){try {//创建http客户端HttpClient client = new HttpClient();//创建post请求,指定请求地址PostMethod post = new PostMethod(url);//设置请求头post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//在头文件中设置转码//添加参数:循环map,把map中的数据变成ListSet<String> keys = params.keySet();List<NameValuePair> paramList = new ArrayList<>();for(String key: keys){String value = params.get(key);paramList.add(new NameValuePair(key, value));}//把list变成数组NameValuePair[] data = paramList.toArray(new NameValuePair[]{}) ;post.setRequestBody(data);//执行请求client.executeMethod(post);//获取结果String result = new String(post.getResponseBodyAsString().getBytes("utf-8"));//打印返回消息状态System.out.println(result);//释放连接post.releaseConnection();return result;} catch (IOException e) {e.printStackTrace();}return null;}
}
5.3.4. 短信网关
1) 短信发送原理

2)短信网关注册

中国网建 : http://www.smschinese.cn/

注册账号
设置签名
查看API文档

3)发送短信

5.4. 完成注册

5.4.1 注册流程


1.基本参数校验
2.手机验证码校验
3.手机是否已经被注册校验
4.保存SSO注册信息
5.保存VIP_Base基本信息

5.4.2 后台注册逻辑

1)DOT封装

public class RegisterDto {private String mobile;private String password;private String  smsCode;

2)service逻辑

@Override
public void register(RegisterDto registerDto) {String mobile = registerDto.getMobile();String password = registerDto.getPassword();String smsCode = registerDto.getSmsCode();//1.判断参数if(StringUtils.isBlank(mobile)){throw new RuntimeException("手机号不能为空");}if(StringUtils.isBlank(password)){throw new RuntimeException("密码不能为空");}if(StringUtils.isBlank(smsCode)){throw new RuntimeException("验证码不能为空");}//判断手机号是否已经被注册Sso ssoFromMysql = baseMapper.selectByPhone(mobile);if(ssoFromMysql != null)throw  new RuntimeException("手机号已经被注册");//2.判断手机验证码String SMSCodeKey = VerifyCodeServiceImpl.SMSCODE_IN_REDIS_KEY_PREFIX+mobile;AjaxResult ajaxResult = commonFeignClient.get(SMSCodeKey);if(!ajaxResult.isSuccess() || ajaxResult.getResultObj() == null){throw new RuntimeException("无效的手机验证码,或过期,请重新发送");}String SMSCodeJson = ajaxResult.getResultObj().toString();SMSCodeSendVo smsCodeSendVo = JSON.parseObject(SMSCodeJson, SMSCodeSendVo.class);if(!smsCodeSendVo.getCode().equals(smsCode.trim())){throw new RuntimeException("错误的手机验证码");}//3.保存sso用户登录信息Sso sso = new Sso();long time = new Date().getTime();sso.setCreateTime(time);//密码加密String salt = UUID.randomUUID().toString();String enPass = MD5.getMD5(password+salt);sso.setPassword(enPass);//保存盐sso.setSalt(salt);sso.setPhone(mobile);baseMapper.insert(sso);//4.保存base基本信息表VipBase vipBase = new VipBase();vipBase.setSsoId(sso.getId());vipBase.setCreateTime(time);vipBase.setRegChannel(1);   //1.pc断vipBase.setRegTime(time);vipBaseMapper.insert(vipBase);
}
5.4.3 位状态处理

1.抽取位状态常量

public class Sso extends Model<Sso> {//手机号的状态public static final long BIT_STATE_PHONE = 1;//邮箱状态public static final long BIT_STATE_EMAIL = 2;//实名认证public static final long BIT_STATE_REAL_AUTH = 4;//支付密码public static final long BIT_STATE_PAY_PASSWORD = 8;

2.抽取位状态方法

//添加位状态
public void addBitState(long bitState){this.bitState = this.bitState | bitState;
}//删除加位状态
public void removeBitState(long bitState){this.bitState = this.bitState ^ bitState;
}//判断包含位状态
public boolean hasBitState(long bitState){return (this.bitState & bitState) > 0;
}

3.设置Sso的位状态

//添加位状态
ssoNew.addBitState(Sso.BIT_STATE_PHONE);

6. 课程总结

6.1.重点

1.图片验证码
2.短信验证码

6.2难点

1.图片验证码
2.短信验证码

6.3.课后作业

1.全天代码

6.4.面试题

1.你们图片验证码怎么处理的
2.你们的手机验证码流程是怎么样的
3.如何防止暴力攻击,比如使用软件来频繁访问短信接口

A091_hrm07_用户中心_注册相关推荐

  1. WEB前后端交互原型通用元件库、常用组件、信息输出、信息输入、信息反馈、综合系列、页面交互、首页、分类页、内容详情、用户中心、注册登录、找回密码、元件库、web元件库、rplib、axure

    WEB前后端交互原型通用元件库.常用组件.信息输出.信息输入.信息反馈.综合系列.页面交互.首页.分类页.内容详情.用户中心.注册登录.找回密码.元件库.web元件库.rplib.axure原型 we ...

  2. 用户中心登录注册整理

    登录: 登录方式 实现逻辑 手机动态密码登录 调用服务层的loginBusiness的动态登录服务 先检验是否超过限制的登录次数 初始化登录事件loginevent 检查用户是否被禁止登录 调用接口给 ...

  3. 北京市社会保险网上服务平台_城镇职工用户登陆_注册手机号更改

    最近因为一件事情,需要登陆北京市社会保险网上服务平台查询社保信息,网站:http://fuwu.rsj.beijing.gov.cn/csibiz/indinfo/login.jsp 但是登陆过程需要 ...

  4. WordPress主题 wpdx 响应式CMS/Blog 含用户中心主题[v3.6版]

    现用主题 wpdx 也已更新至 3.6 版本,在原有横向布局(主菜单在左边)的基础上,再添加垂直布局(主菜单在上方),每种布局都有 5 种配色,选择更自由!同时主菜单已经支持 3 级菜单啦!依旧响应式 ...

  5. 微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关

    微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关 1. 微服务简介 1.1 服务架构演变 1.2 SpringCloud ...

  6. layui设置按钮不可点击_(eblog)7、博客发布收藏、用户中心的设置

    小Hub领读: 继续我们的eblog,今天来完成博客文章收藏,用户中心的设置! 项目名称:eblog 项目 Git 仓库:https://github.com/MarkerHub/eblog(给个 s ...

  7. 用户管理系统_【20201204】做个用户管理系统(18)——注册功能的实现(三)...

    1. 介绍 1.1 介绍 福哥今天要带着大家开发TFUMS系统的注册功能的处理程序了.这个处理程序会调用模型user的add方法进行创建用户的操作,模型user的add方法会先检查用户名是否被占用了, ...

  8. 14、阿里云短信Demo演示、Http的Get请求和Post请求演示、httpClient工具类演示、发送短信模块搭建、搭建用户中心模块、完成user注册基本功能、验证码存入redis、短信验证码注册

    阿里云短信Demo演示 一.前端部分 无前端. 二.后端部分 1.创建发送短信测试模块SmsSendDemo,不用使用骨架. 2.在pom文件中引入依赖坐标 <dependency>< ...

  9. 关于中国版权用户中心注册账号和实名认证问题

    在网站 "中国版权用户中心" 注册账号和实名认证遇到的坑~ 1.用户名错误 按照提示填写用户名,却一直报错,网上搜索到网站有比较多的吐槽,以为自己也要修改网站的JavaScript ...

最新文章

  1. 经常用得到的安卓数据库基类
  2. mysql 手工注入教程_mysql手工注入步骤
  3. SpringBoot2.0 整合 ElasticSearch框架,实现高性能搜索引擎
  4. ansible(3)——主机列表,ssh,公钥私钥
  5. String类得常用方法
  6. 【正则化】Label Smoothing详解
  7. “数据结构+算法”视角的Asprova
  8. ssh-keygen+ssh-copy-id无密码登录远程LINUX主机(转载)
  9. 电脑文件备份到哪里最安全?
  10. MySQL Cluster测试过程中的错误汇总--ERROR 1296 (HY000)等等
  11. matlab数字图像处理库,MATLAB06:数字图像处理
  12. vue项目json格式化显示
  13. Adobe After Effect的 安装 教程
  14. 大数据(线性/非线性)降维方法(PCA,LDA,MDS,ISOMAP,LLE)
  15. 从零开始的Nginx详解(3)【Nginx-Https服务配置详解】
  16. 百度语音合成Rest API使用
  17. 微习惯瘦身,一天一个俯卧撑就够了吗?
  18. 【echarts实现】中国地图 世界地图
  19. 三相永磁同步电机的矢量控制学习笔记一
  20. 期货开户CTP高性能高容量高可靠性

热门文章

  1. 鸿蒙系统电视k歌,前沿讯息:华为电视K歌模式 开启当贝音乐 曲库任意选 功能很强大...
  2. 上半年营收256亿,转型的陆金所能否在纽交所站稳脚跟?
  3. android图片异步加载图片,Android 异步加载图片分析总结
  4. 代码随想录算法训练营第07天 | LeetCode 454.四数相加2,383. 赎金信,15. 三数之和,18. 四数之和,总结
  5. 使用Transformer构建自己的机器翻译服务
  6. 在Linux服务器部署Halo博客系统及配置HTTPS
  7. 日语学习 第4篇 部屋(へや)に机(つくえ)と椅子(いす)があります
  8. 1 W 字 | 硬刚 MySQL
  9. Java 集合系列3、骨骼惊奇之LinkedList
  10. OA系统需求功能介绍