Java实现短信验证码

更新时间:2023-05-13 13:05:19 阅读: 评论:0

Java实现短信验证码
⼤家好,我是孙嵓,短信验证码相信⼤家都不陌⽣吗,但是短信验证码怎么⽣成的你真的了解吗,本⽂揭⽰本⼈项⽬中对短信验证码的。项⽬需求
⽤户注册/忘记密码添加短信验证码
需求来由
登录注册页⾯需要确保⽤户同⼀个⼿机号只关联⼀个账号确保⾮⼈为操作,避免系统⽤户信息紊乱增加系统安全性
代码实现
同事提供了WebService接⼝,很好,之前没调过,⼜增加了困难。
这边⽤的阿⾥云的短信服务,废话少说上图,呸,上代码—
发送验证码⽅法
public AjaxResult ndVerificationCode(LoginBody loginBody){
//拼装redis的key
String redisCodeKey = Constants.RECRUIT_CODE_KEY + UrName();
//通过判断过期时间检验是否发送过验证码如果发送直接return
Expire(redisCodeKey)>=0){
(TipsConstants.YZM_SEND_ALREADY);
}
//⽣成随机6位验证码
String redisCodeValue = ateSmsCode();
谦虚的英文//验证码类型这是根据同事给的webrvice的⽂档单独封装的⽬前先这么写了;判断其是注册还是忘记密码
佛手瓜苗VerificationCodeType verificationCodeType = VerificationCodeType());
String templateCode = null;
switch(verificationCodeType){
ca REGISTER:
templateCode = Code();
break;
ca FORGET_PASSWORD:
templateCode = VerificationCodeType.Code();
break;
default:
break;
}
/
/webrvice接⼝需要json格式的参数
JSONObject jsonObject =new JSONObject();
jsonObject.put(WebServiceConstants.CODE, redisCodeValue);
Map<String, String> resultMap = SMSUtils.UrName(),templateCode,jsonObject);
//判断webrvice接⼝返回的结果
if(!(WebServiceConstants.SEND_SMS_RESULT).equals(Constants.SUCCESS)){
logger.(WebServiceConstants.OUT_MSG));
logger.(WebServiceConstants.BIZ_ID));
(TipsConstants.MSG_SERVER_ERROR);
}
//存储到redis设置过期时间,这⾥设置了60s,根据需求来
redisCache.tCacheObject(redisCodeKey, redisCodeValue,60, TimeUnit.SECONDS);
return AjaxResult.success();
}
注册⽅法
public AjaxResult register(LoginBody loginBody){
//拼装redis key
String redisCodeKey = Constants.RECRUIT_CODE_KEY + UrName();
五人斗地主//redisCache封装了redis的⽅法;
//获取验证码判断验证码是否为空;输⼊的验证码与短信验证码是否⼀致
String redisCodeValue = CacheObject(redisCodeKey);
if(StringUtils.isEmpty(redisCodeValue)||!VerificationCode().equals(redisCodeValue)){ (TipsConstants.YZM_ERROR);
}
//查表校验⽤户是否注册
SysUr existUr = sysUrMapper.UrName());
if(!ObjectUtil.isEmpty(existUr)){
(TipsConstants.EXIST_USER_ERROR);
}
//对象copy,创建SysUr对象
SysUr sysUr = pyProperties(loginBody, SysUr.class, UrConstants.PASSWORD);    sysUr.Password()));
//插⼊⽤户信息
sysUrMapper.inrtUr(sysUr);
return AjaxResult.success(TipsConstants.REGISTER_SUCCESS);
}
忘记密码
public AjaxResult forgetPwd(LoginBody loginBody){
//拼装redis的key
String redisCodeKey = Constants.RECRUIT_CODE_KEY + UrName();
//获取验证码
String redisCodeValue = CacheObject(redisCodeKey);
if(!VerificationCode().equals(redisCodeValue)){
(TipsConstants.YZM_ERROR);
}
/
/查表查询⽤户是否存在
SysUr sysUr = sysUrMapper.UrName());
if(ObjectUtil.isEmpty(sysUr)){
(TipsConstants.NO_USER);
}
//密码加密
loginBody.Password()));
//重置密码
return AjaxResult.success();
}
前端代码
这⾥只粘贴了发送验证码改变按钮的⽅法
ndCode(type){
this.$isterForm.validateField('phone',(phoneError)=>{
if(!phoneError){
//短信验证码最⼤请求次数校验
isterForm).then(respon =>{
de !==200){
}el{
this.msgSuccess('发送成功,请注意查收短信')
}
//发送验证码按钮修改
if(!questMax){
let time =60
this.buttonText ='已发送'
this.isDisabled =true
if(this.flag){
this.flag =fal
let timer =tInterval(()=>{
time--
this.buttonText = time +' 秒'
if(time ===0){
clearInterval(timer)
this.buttonText ='重新获取'
this.isDisabled =fal
怎么删除分页符this.flag =true
}
},1000)
}
}
})
}
})
},
编码中遇到的问题
1.webrvice如何调⽤?
⼀开始导了很多关于webrvice的相关依赖,结果掉不通没办法只能⽤Hutool了,nd返回的是⼀个xml,再⽤documet将其解析就ok 了。
SoapClient soapClient = MsgUrl())
.tMethod(Code(), NamespaceUri())
.tParams(map,fal);
String result = soapClient.nd()
2.不能让⽤户⽆限制的请求发送验证码
据说短信平台有验证逻辑,为了安全还是给系统封了⼀层;这⾥通过注解,aop配合redis计数器进⾏最⼤请求次数验证。
代码如下
注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckRequestTimes {
/**
* 最⼤请求次数
*/
String maxTimes()default"10";
/**
* 整个系统最⼤请求次数
*/
String maxSystermTimes()default"1000";
/**
巡盐御史
* 请求类型
*/
RequestEnums reqType()default RequestEnumsMON;
/**
* 请求次数上限错误信息提⽰
*/
String errorMsg()default TipsConstants.REQUEST_TIMES_MAX
}
Aspect
夏秋季征兵
这部分代码我个⼈认为设计⽐较巧妙,可供读者思考,多利⽤设计模式思想去开发代码,让代码更优雅、更健壮、更可⽤,crud也有编出⾃⼰的⾻⽓(本实例涵盖了单例,模板⽅法)
@Aspect
@Component
@Order(2)
public class CheckRequestAspect {
@Autowired
RedisService redisService;
@Autowired
TokenService tokenService;
private static Logger logger = Logger(CheckRequestAspect.class);
//防⽌并发,添加关键字实现共享
private volatile ConcurrentHashMap<RequestEnums, RequestTimesAbstract> reqTimesProcessMap;
@PostConstruct
public void initExcelProcessorFactory(){
//dcl 双重检查锁,也可进⾏懒散加载。因为现在基于spring容器单例,此锁可适当调整
if(MapUtil.isNotEmpty(reqTimesProcessMap)){
return;
}
//眼熟不这叫懒汉式单例
synchronized(this){
if(ObjectUtil.isNull(reqTimesProcessMap)){
reqTimesProcessMap =new ConcurrentHashMap(8);
}
//这⾥其实可以采⽤⼯⼚⽅法去改造,由于业务没有太多类型所以就不设计⼯⼚了
reqTimesProcessMap.put(RequestEnumsMON,new UrCommReqTimes());
reqTimesProcessMap.put(RequestEnums.SMS,new SMSCodeReqTimes());
}
}
/**
* 切⼊点
*/
@Pointcut("@annotation(com.annotation.CheckRequestTimes)")
public void checkPoint(){
}
/**
* 环绕获取请求参数
*
* @param proceedingJoinPoint
* @param proceedingJoinPoint
* @return
*/
@Around("checkPoint()")
public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
//获取⽅法上的注解
CheckRequestTimes checkRequestTimes =getAnnotation(proceedingJoinPoint);
Object[] args = Args();
//判断是否到达最⼤请求次数,这⾥为了应对不同请求类型的处理⽅式写了⼀个抽象类,
//便于扩展维护,沿⽤了了模板⽅法设计模式的思想
if(!(qType()).judgeMaxTimes(args, checkRequestTimes, redisService)){ (HttpStatus.REQUEST_MAX, Msg());
}
//执⾏请求⽅法
Object proceed = null;
try{
proceed = proceedingJoinPoint.proceed();
}catch(Throwable throwable){
<(Message(), throwable);
}
return proceed;
}紧张的近义词是什么
/**
* 获取⽅法上的注解以便拿到对应的值
*
* @param proceedingJoinPoint
* @return
*/
private CheckRequestTimes getAnnotation(ProceedingJoinPoint proceedingJoinPoint){
MethodSignature signature =(MethodSignature) Signature();
Method method = Method();
if(method != null){
Annotation(CheckRequestTimes.class);
}
return null;
}
}
抽象模板类
public abstract class RequestTimesAbstract {
/**
* 判断是否到达请求最⼤次数
* @param object 参数
* @param checkRequestTimes  注解
* @param redisService  redis服务
烤鸭舌
* @return
*/
public abstract boolean judgeMaxTimes(Object object, CheckRequestTimes checkRequestTimes, RedisService redisService); }
短信模板⼦类

本文发布于:2023-05-13 13:05:19,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/892713.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:验证码   请求   短信   是否   发送   次数   判断
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图