手机短信验证码登录功能的开发实录(机器识别码、短信限流、错误提示、发送验证码倒计时60秒)

简介: 手机短信验证码登录功能的开发实录(机器识别码、短信限流、错误提示、发送验证码倒计时60秒)


短信验证码是通过发送验证码到手机的一种有效的验证码系统,作为比较准确和安全地保证购物的安全性,验证用户的正确性的一种手段,几乎网站登录都会使用该方式。

其特点是依据某些验证码接入商提供手机短信验证码服务,各网站通过接口发送请求到接入商的服务器,服务器发送随机数字或字母到手机中,由接入商的服务器统一做验证码的验证。


项目分析

  1. 开通阿里云、腾讯云等短信API端口;
  2. 为防止机器批量发送验证码,设置机器识别码,设置5分钟内发送的次数,进而予以限流;
  3. 发送信息错误时,进行明确的信息提示;
  4. 完成信息验证,执行业务正常逻辑;


核心代码

1.外部js库调用

    <script type="text/javascript" src="static/js/jquery.min.js"></script>
    <!--layui封装库-->
    <script src="static/layui/layui.js" charset="utf-8"></script>
    <link rel="stylesheet" href="static/layui/css/layui.css">


2.HTML容器构建

<div style="margin-top: 10px;padding: 20px;">
    <form class="layui-form layui-form-pane">
        <div class="layui-form-item">
            <label for="L_user_phone" class="layui-form-label">手机号码</label>
            <div class="layui-input-inline"><input type="text" id="L_user_phone" name="user_phone" class="layui-input" lay-verify="user_phone"></div>
            <div class="layui-form-mid layui-word-aux"><span class="x-red">* 手机号码,作为登录账户唯一凭证,如:13500000001。</span></div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">识别码</label>
            <div class="layui-input-inline"><input type="text" name="captcha" id="captcha" lay-verify="required" autocomplete="off" class="layui-input"></div>
            <div class="layui-form-mid layui-word-aux"> <img src="?m=Login&a=loginDeal&act=getCode" id="getCode" alt="" title="点击刷新验证码" style="cursor: pointer;"><span class="x-red"> * </span> 发送手机短信验证</div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">短信验证码</label>
            <div class="layui-input-inline"><input type="text" name="smscode" id="smscode" lay-verify="smscode" autocomplete="off" class="layui-input" disabled="disabled"></div>
            <div class="layui-input-inline">
                <input type="button" class="layui-btn layui-btn-primary" id="btnSendCode" disabled="disabled" value="获取验证码">
            </div>
        </div>
        <div class="layui-form-item">
            <button class="layui-btn layui-btn-fluid layui-btn-normal" lay-filter="save" id="L_add" lay-submit=""> 确认登录 </button>
        </div>
    </form>
</div>


3.javaScript业务逻辑验证

  • 验证手机号和短信验证码规则
        //自定义验证规则
        form.verify({
            user_phone: [/^1[3|4|5|6|7|8|9]\d{9}$/, '手机必须11位,只能是数字!']
            , smscode: [/[\S]+/, "验证码为6位数且5分钟内有效"]
        });


  • 机器识别码验证

获取实际图片识别码

    $("#getCode").click(function () {
            $(this).attr("src", '?m=Login&a=loginDeal&act=getCode&' + Math.random());
        });


  • 发送短信验证码倒计时60秒
        var wait = 60;
        function time(o) {
            if (wait == 0) {
                o.removeAttribute("disabled");
                o.value = "获取验证码";
                wait = 60;
            } else {
                o.setAttribute("disabled", true);
                o.value = "重新发送(" + wait + ")";
                wait--;
                setTimeout(function () {
                    time(o);
                }, 1000);
            }
        }


  • 获取识别码和验证码的业务逻辑
 //单击发送验证码;
                document.getElementById("btnSendCode").onclick = function () {
                    var captcha = $("#captcha").val();
                    //获取识别码;
                    $.getJSON("?m=Login&a=loginDeal&act=captcha", {mobile: mobile, captcha: captcha}, function (res) {
                        if (res.code == '0') {
                            layer.msg(res.msg, {icon: 1, time: 2000});
                        } else {
                            if (wait != 60) {
                                layer.alert("请" + wait + "秒后再试!", {icon: 3, time: 2000})
                                return;
                            }
                            time(document.getElementById("btnSendCode"));
                            $.getJSON("?m=Sms&a=smsDeal&act=verify", {
                                mobile: mobile,
                                captcha: captcha
                            }, function (res2) {
                                //console.log(res2.send.Code);
                                if (res2.send.Code != "OK") {
                                    layer.alert("短信限流,请等待5分钟", {icon: 3, time: 2000})
                                }
                            });
                        }
                    });
                }


针对不同平台的业务逻辑,对返回的短信参数进行输出,提示用户操作。

 if (res2.send.Code != "OK") {
   layer.alert("短信限流,请等待5分钟", {icon: 3, time: 2000})
 }


  • 执行业务正常逻辑
 //监听提交;
        form.on('submit(save)', function () {
            $.ajax({
                type: "post",
                url: "?m=Login&a=loginDeal&act=smsCode",
                async: true,
                data: {
                    user_phone: $('#L_user_phone').val(),
                    smscode: $('#smscode').val()
                },
                dataType: "json",
                success: function (res) {
                    //console.log(res);
                    if (res.code == 0) {
                        layer.msg(res.msg, {icon: 1, time: 2000});
                    } else {
                        layer.msg(res.msg, {icon: 1, time: 2000}, function () {
                            var index = parent.layer.getFrameIndex(window.name);
                            parent.layer.close(index);
                            window.parent.location.href = "?m=Index&a=my";
                        });
                    }
                },
                error: function (err) {
                    console.log(err);
                }
            });
            return false;
        });


4.后端验证逻辑

  • 生成随机机器识别码
    case "getCode";
        require_once "libs/vcode.class.php";
        $obj = new vcode();//实例化;
        $_SESSION['authcode'] = $obj->authcode;
        die($obj->output());
        break;
  • 验证机器识别码
  //网站识别码;
    case "captcha";
        $user_phone = get_param('mobile');
        $captcha = isset($_GET["captcha"]) ? trim($_GET["captcha"]) : '';
        if ($captcha != $_SESSION['authcode']) {
            $res['code'] = "0";
            $res['msg'] = "识别码错误";
            die(json_encode_lockdata($res));
        } else {
            $res['code'] = "1";
            $res['msg'] = "识别码通过";
            //验证码自动销毁;
            session_destroy();
            die(json_encode_lockdata($res));
        }
        break;


  • 发送短信流(次数)判断
case "verif case "verify";
        require "libs/api_demo/SmsDemo.php";/*阿里云短信SDK*/
        $rmdCode = rand(111111, 999999);//随机验证码
        $templateCode = 'SMS_165690909';//调用模版
        $signName = '言医';//签名
        $mobile = get_param('mobile');//手机号
        if ($mobile == "") {
            die("越权访问!");
        }
        //增加记录;
        addlogs($mobile, 'smscode', '', time(), getip());
        //读取数据库记录;
        $fromTime = time() - 300;
        $toTime = time();
        $sql = "select log_id FROM " . $db->table('log') . " WHERE 1";
        $sql .= " AND logs = 'smscode' AND log_ip ='" . getip() . "'";
        $sql .= " AND log_time > " . $fromTime . " AND log_time <" . $toTime . "";
        $sql .= " ORDER BY log_id DESC";
        $row = $db->queryall($sql);
        if (count($row) >= 5) {
            $res['code'] = 0;
            $res['msg'] = '5分钟内最多发送5次短信.';
            $res['total'] = count($row);
            die(json_encode_lockdata($res));
        } else {
            $send = SmsDemo::sendSms($mobile, $signName, $templateCode, $rmdCode, '', '', '', '', 1);
            $res['code'] = 1;
            $res['send'] = $send;
            $_SESSION['code'] = $rmdCode;
            die(json_encode_lockdata($res));
        }
        break;

总结

一个简单的手机短信验证码登录,涉及到的方方面面比较多。在发送短信次数的限制上,本系统作为正常的业务逻辑进行判断和限流,同时对于阿里云和腾讯云也有对应的限制规则,需要在平台上进行设置。

@漏刻有时


相关文章
|
机器学习/深度学习 存储 人工智能
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
MNN-LLM App 是阿里巴巴基于 MNN-LLM 框架开发的 Android 应用,支持多模态交互、多种主流模型选择、离线运行及性能优化。
17637 81
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
|
存储 算法 API
【01】整体试验思路,如何在有UID的情况下获得用户手机号信息,python开发之理论研究试验,如何通过抖音视频下方的用户的UID获得抖音用户的手机号-本系列文章仅供学习研究-禁止用于任何商业用途-仅供学习交流-优雅草卓伊凡
【01】整体试验思路,如何在有UID的情况下获得用户手机号信息,python开发之理论研究试验,如何通过抖音视频下方的用户的UID获得抖音用户的手机号-本系列文章仅供学习研究-禁止用于任何商业用途-仅供学习交流-优雅草卓伊凡
4794 82
|
存储 人工智能 编译器
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
1135 11
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
|
安全 Go 开发工具
HarmonyOS5云服务技术分享--手机号登录教程
本文详细讲解了在HarmonyOS中集成手机号认证功能的全流程。首先分析了手机号认证的优势,如用户友好、安全性强及快速接入。接着介绍了环境准备步骤,包括集成AGC认证SDK、开启手机认证能力及添加必要权限。核心功能实现部分提供了新用户注册、密码登录和验证码登录的代码示例。此外,还涵盖了账号管理技巧,如修改绑定手机号、重置密码等,并提供了避坑指南和扩展能力建议,帮助开发者轻松实现安全高效的认证系统。
|
存储 API 数据安全/隐私保护
【02】整体试验思路,在这之前我们发现sec_uid,sec_uid是什么和uid的关系又是什么?相互如何转换?python开发之理论研究试验,如何通过抖音视频下方的用户的UID获得抖音用户的手机号-本系列文章仅供学习研究-禁止用于任何商业用途-仅供学习交流-优雅草卓伊凡
【02】整体试验思路,在这之前我们发现sec_uid,sec_uid是什么和uid的关系又是什么?相互如何转换?python开发之理论研究试验,如何通过抖音视频下方的用户的UID获得抖音用户的手机号-本系列文章仅供学习研究-禁止用于任何商业用途-仅供学习交流-优雅草卓伊凡
3578 6
|
存储 NoSQL 前端开发
美团面试:手机扫描PC二维码登录,底层原理和完整流程是什么?
45岁老架构师尼恩详细梳理了手机扫码登录的完整流程,帮助大家在面试中脱颖而出。该过程分为三个阶段:待扫描阶段、已扫描待确认阶段和已确认阶段。更多技术圣经系列PDF及详细内容,请关注【技术自由圈】获取。
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
5186 5
|
缓存 前端开发 IDE
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
593 0
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
网络协议 Android开发 数据安全/隐私保护
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
13579 2
|
监控 安全 Android开发
【新手必读】Airtest测试Android手机常见的设置问题
【新手必读】Airtest测试Android手机常见的设置问题
1064 0

热门文章

最新文章