简析发送手机验证码原理


在一般互联网网站(如淘宝、京东等)注册账号或者找回密码时通常让用户进行手机号码进行 发送验证码验证,这种方式能有效的保证帐号安全,下面来解析一下它的原理。

在这里插入图片描述

整体流程如下图如示,包括手机验证码发送和校验流程。简而言之,手机短信?验证码,是通过发送验证码到手机,然后输入接收到的验证码到登录框,两者一致就能通过审核,成功登录,否则失败。

在这里插入图片描述

通常验证码会以手机号码作缓存 key,验证码作为缓存 value,验证码有效时间作为过期时间存放到缓存中,校验手机验证码时直接根据手机号码取出缓存中的验证码与用户输入的验证码进行比对即可。

发放手机验证码

为了防止恶意发放,发送手机验证码时需要设置每次发放短信的间隔。流程如下:

  • Step 1:校验是否频繁发送手机验证码(比较当前时间与上一次缓存更新时间是否超过指定时间间隔)
  • Step 2:若非频繁发送,则随时生成4位验证码
  • Step 3:将手机号和验证码放入缓存中。其中其中cache结构: 手机号作为 cache key,验证码作为 cache value, 验证码过期时间作为 cache 过期时间
  • Step 4:调用短信服务执行真实发放逻辑

伪代码如下:

public void sendPoneCode(String nationCode, String phone) {
        // 1. 拼接为区号,如+86是中国的国际区号
        String target = nationCode + phone;

        // 2. 校验是否发放频繁
        if(!checkCanSend()){
            System.out.printf("发送过于频繁,请稍等!");
            return;
        }

        // 3. 生成手机随机码
        String phoneCode = generatePhoneCode();

        // 4. 放入 cache
        putCache(target, phoneCode, EXPIRE);

        // 4. 调用短信服务执行发送
        dosSendPoneCode(target, phoneCode);
    }

    private boolean checkCanSend() {
        Long curTime = System.currentTimeMillis();
        /*
         * 获取 cache 的更新时间,其中cache结构: target 作为 cache key,phoneCode 作为 cache value, expire 作为 cache 过期时间
         */
        Long cacheUpdateTime = getCacheUpdateTime();
        /*
         * 比较 cache 的更新时间与当前时间差值是否大于短信发送间隔
         */
        if(curTime - cacheUpdateTime < INTERVAL) {
            return true;
        }
        return false;
    }


    private static String generatePhoneCode() {
        StringBuilder phoneCode = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i <4 ; i++) {
            phoneCode.append(random.nextInt(10));
        }
        return phoneCode.toString();
    }

    private void putCache(String target, String phoneCode, int expire) {
        /**
         * target 作为 cache key,phoneCode 作为 cache value, expire 作为 cache 过期时间
         * 省略具体cache put 调用
         */
    }

    private void dosSendPoneCode(String target, String phoneCode) {
        // 调用短信服务执行真实发送逻辑,省略
    }
手机验证码校验

手机验证校验逻辑比较简单,从缓存中取出缓存中的验证码,与用户手机输入的验证码直接进行比对即可,伪代码如下:


    public boolean validatePoneCode(String nationCode, String phone, String code) {
        // 1. 拼接为区号,如+86是中国的国际区号
        String target = nationCode + phone;

        // 2. 从 cache 中取出
        String cachePoneCode = getValueFromCache(target);

        // 3. 比较是否一样
        if(code.equals(cachePoneCode)) {
            return true;
        }
        return false;
    }
小结

文中因超出标题的范畴并未描述短信服务的发放原理,短信服务一般由第三方服务来提供(比如阿里的SMS等),对接后可直接使用其sdk进行发送。事实上手机发送及验证码流程并没有神秘的地方,文中发送和校验手机验证码流程可以直接借鉴到日常项目中。

欢迎如转载,请注明出处!欢迎关注微信公众号:方辰的博客。

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值