手机短信验证码实现

1.前端点击按钮发送短信验证码(需要校验参数)

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")
                    };


                    //4.发送ajax请求
                    this.$http.post("/common/verifycode/sendSmsCode", param).then(res => {
                        var ajaxResult = res.data;
                        if (ajaxResult.success) {
                            $.alert("手机验证码已经发送到您的手机,请在3分钟内使用");
                            //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);
                        }
                    }).catch(error => {
                        //4.3.发送失败:提示,恢复按钮
                        sendBtn.attr("disabled", false);
                        $.alert("发送失败:" + error.message);
                    })
                }

2.后端接收请求,校验参数,生成验证码,通过短信发送给用户

controller接收请求

@PostMapping(value="/sendSmsCode")
public JSONResult getSmsCode(@RequestBody @Validated SMSParamDto param){
   verifycodeService.getSmsCode(param);
   return JSONResult.success();
}

service 

 /**
   * 判断参数,判断条件
   * 校验图形验证码
   * 校验手机验证码,有就使用上一次的,没有就新发送一个
   * 发送短信
   * 将短信信息存到数据库
   * @param param
   */
void getSmsCode(SMSParamDto param);

具体步骤

1.判断参数(SMSParamDto中判断了),判断条件

2.校验图形验证码

3.校验手机验证码,有就使用上一次的,没有就新发送一个

4.发送短信(我这里直接打印在控制台,实际情况需要调用短信接口发送短信)

5.将短信信息存到数据库

6.手机验证码发送成功,删除图形验证码

dto

@Data
public class SMSParamDto {
    @NotEmpty(message = "手机号不能为空")
    private String mobile;
    @NotEmpty(message = "图形验证码不能为空")
    private String imageCode;
    @NotEmpty(message = "无效请求")
    private String imageCodeKey;
}
constants(抽了一个常量类)
public class AllConstants {

    // 基本常量
    public class BaseConstants{
        // 一分钟的毫秒数
        public static final int MILLISECOND_ONE_MINS = 60000;
        // 一分钟的秒数
        public static final int SECOND_ONE_MINS = 60;
    }
}

impl

 需要注入

@Autowired
private RedisTemplate<Object,Object> redisTemplate;

@Autowired
private IMessageSmsService smsService;
   
@Autowired
private SMSVerifycodeProperties smsProperties;

@Autowired
private IBlockService blockService;
@Override
    public void getSmsCode(SMSParamDto param) {
        // 1.校验图形验证码
        String imageCode = (String) redisTemplate.opsForValue().get(param.getImageCodeKey());
        if (imageCode == null){
            throw new GolbalException("图形验证码已过期");
        }
        if (!imageCode.equalsIgnoreCase(param.getImageCode())){
            throw new GolbalException("图形验证码错误");
        }


        // 判断手机号是否被拉黑
        Block phone = findBlockByPhone(param.getMobile());
        if (phone != null){
            throw new GolbalException("您已经被禁用发送短信验证码,请联系管理员!");
        }


        // 2.校验手机验证码,有就使用上一次的,没有就新发送一个
//        String smsKey = String.format(AllConstants.PrefixConstants.KEY_SMS_PREFIX + param.getMobile());
        String smsKey = "register:" + param.getMobile();
        SMSLog2Redis lastSMSLog2Redis = (SMSLog2Redis) redisTemplate.opsForValue().get(smsKey);

        Date now = new Date();
        String smsCode = null;
        if (lastSMSLog2Redis != null){
            // 2.1有验证码,判断手机验证码的发送时间,手机小于60s报错,大于60s且验证码未被使用,就使用之前的验证码
            if (now.getTime() - lastSMSLog2Redis.getSendTime().getTime() < AllConstants.BaseConstants.MILLISECOND_ONE_MINS){
                // 抛异常
                throw new GolbalException("操作频繁,请稍后重试!");
            }
            // 使用之前的验证码
            smsCode = lastSMSLog2Redis.getCode();
        }else {
            // 2.2没有验证码,生成新的验证码(随机字符串)
            smsCode = StrUtils.getRandomString(smsProperties.getLength());
        }
        
        // 3.将验证码存到redis  key(手机号+业务键)- value(验证码,时间)
        SMSLog2Redis smsLog2Redis = new SMSLog2Redis(smsCode, now);
        redisTemplate.opsForValue().set(smsKey,smsLog2Redis,smsProperties.getExpire(),TimeUnit.MINUTES);
        // 4.发送短信
        String content = "您的验证码为:" + smsCode + ",请在" + smsProperties.getExpire()/AllConstants.BaseConstants.SECOND_ONE_MINS + "分钟内使用!";
        log.info(content);
        // 5.将短信信息存到数据库
        smsService.save(content,param.getMobile(),"注册短信验证码");
        // 6.手机验证码发送成功,删除图形验证码
        redisTemplate.delete(param.getImageCodeKey());
    }

    private Block findBlockByPhone(String mobile) {
        return blockService.findByPhone(mobile);
    }

抽出了一个方法

private Block findBlockByPhone(String mobile) {
        return blockService.findByPhone(mobile);
 }

service

Block findByPhone(String phone);

impl

public Block findByPhone(String phone){
   Wrapper<Block> query = new EntityWrapper<>();
   query.eq("phone",phone);
   return super.selectOne(query);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值