dede表单短信验证码如何实现?

99ANYc3cd6
预计阅读时长 42 分钟
位置: 首页 DEDE建站 正文

下面我将为你提供一个详细的、分步的集成指南,这个过程会涉及到几个核心文件:

dede 表单 短信验证码
(图片来源网络,侵删)
  1. 模板文件: plus/diy.php (用于显示表单)
  2. 处理文件: plus/diy.php (用于接收和处理表单数据)
  3. 短信服务商: 选择一个平台并获取 API Key 和 Secret。

核心思路

整个流程如下:

  1. 用户填写手机号:在表单中添加一个手机号输入框。
  2. 点击“获取验证码”:前端通过 JavaScript 发送一个请求到后端,请求后端调用短信 API 发送验证码。
  3. 后端发送验证码
    • 后端接收到请求后,生成一个随机的验证码(如 6 位数字)。
    • 将这个验证码和用户手机号关联起来(通常存储在 Session 中),并设置一个有效期(如 5 分钟)。
    • 调用短信服务商的 API,将验证码内容发送到用户的手机上。
  4. 用户提交表单:用户填写完所有信息(包括手机号和收到的验证码)后,点击提交。
  5. 后端验证
    • 后端接收到表单提交后,首先从 Session 中取出之前存储的验证码。
    • 比较用户提交的验证码和 Session 中的验证码是否一致。
    • 如果一致,则验证通过,继续执行原有的表单入库逻辑;如果不一致,则提示验证码错误,并阻止表单提交。

第一步:准备工作

  1. 选择短信服务商

    • 国内主流的有:阿里云短信服务、腾讯云短信服务、容联云通讯、Twilio 等。
    • 注册账号并完成实名认证。
    • 创建应用,获取 API Key (或 AccessKey ID) 和 API Secret (或 AccessKey Secret)。
    • 在短信服务后台,创建一个短信签名(如 [你的网站名称])和短信模板(如 【验证码】{1},您正在进行{2}操作,5分钟内有效,请勿泄露。,注意模板变量要和代码中对应)。
  2. 了解 DedeCMS 文件结构

    • 你的自定义表单文件位于 /plus/diy.php
    • 你的模板文件位于 /templets/plus/ 目录下,diyform.htm

第二步:修改模板文件 (diyform.htm)

假设你已经有了一个自定义表单,现在需要添加手机号和验证码字段。

dede 表单 短信验证码
(图片来源网络,侵删)
  1. 在表单中添加手机号和验证码输入框

    <form name='myform' action="/plus/diy.php" enctype="multipart/form-data" method="post">
        <input type="hidden" name="action" value="post" />
        <input type="hidden" name="diyid" value="1" />  <!-- 1 是你的表单ID -->
        <input type="hidden" name="do" value="2" />
        <!-- 其他表单字段... -->
        <p><input type="text" name='name' placeholder='您的姓名' /></p>
        <p><input type="text" name='content' placeholder='留言内容' /></p>
        <!-- 新增:手机号输入框 -->
        <p>
            <input type="text" name="tel" id="tel" placeholder="请输入手机号" />
        </p>
        <!-- 新增:验证码输入框和获取验证码按钮 -->
        <p>
            <input type="text" name="sms_code" id="sms_code" placeholder="请输入短信验证码" style="width: 150px; display: inline-block;" />
            <input type="button" id="getSmsCode" value="获取验证码" style="width: 120px;" />
        </p>
        <p><button type="submit">提交</button></p>
    </form>
  2. 添加 JavaScript 代码处理“获取验证码”逻辑

    diyform.htm 文件的底部,</body> 标签前,添加以下 JS 代码,这段代码会监听按钮点击,并异步请求后端发送验证码。

    <script src="/static/js/jquery.min.js"></script> <!-- 确保引入了jQuery -->
    <script>
    $(function(){
        var isSending = false; // 防止重复点击
        $('#getSmsCode').click(function(){
            if (isSending) return;
            var tel = $('#tel').val();
            if(!tel || !/^1[3-9]\d{9}$/.test(tel)){
                alert('请输入正确的手机号');
                return;
            }
            isSending = true;
            $(this).val('发送中...').prop('disabled', true);
            // 发送AJAX请求到后端发送短信
            $.ajax({
                url: '/plus/diy.php', // 发送到同一个处理文件
                type: 'POST',
                data: {
                    action: 'sendSms', // 自定义的动作标识
                    tel: tel
                },
                dataType: 'json',
                success: function(res){
                    if(res.code == 200){
                        alert('验证码已发送,请注意查收!');
                        startCountDown(); // 开始倒计时
                    } else {
                        alert(res.msg || '发送失败,请稍后重试');
                    }
                },
                error: function(){
                    alert('网络错误,请稍后重试');
                },
                complete: function(){
                    isSending = false;
                    $('#getSmsCode').prop('disabled', false);
                    if(res.code != 200) {
                        $('#getSmsCode').val('获取验证码');
                    }
                }
            });
        });
        // 倒计时函数
        function startCountDown(){
            var countdown = 60;
            var btn = $('#getSmsCode');
            var timer = setInterval(function(){
                if (countdown == 0) {
                    clearInterval(timer);
                    btn.val('获取验证码');
                } else {
                    btn.val(countdown + '秒后重试');
                    countdown--;
                }
            }, 1000);
        }
    });
    </script>

第三步:修改处理文件 (plus/diy.php)

这是最关键的一步,我们需要在这个文件里加入发送短信和验证短信的逻辑。

dede 表单 短信验证码
(图片来源网络,侵删)
  1. 引入短信发送类

    • plus/diy.php 文件的最顶部,require_once(dirname(__FILE__)."/../include/common.inc.php"); 这行之后,引入你自己的短信发送类文件。
    • 你需要自己写一个 SmsSender.php,或者直接在这里写发送函数,为了代码清晰,我们建议创建一个类。
    • /include/ 目录下创建 SmsSender.php 文件,内容如下(这里以 阿里云短信 为例,其他服务商请替换相应代码):
    // /include/SmsSender.php
    <?php
    class SmsSender {
        // 阿里云配置信息
        private $accessKeyId = 'LTAI5t6...'; // 你的 AccessKey ID
        private $accessKeySecret = 'your_secret...'; // 你的 AccessKey Secret
        private $signName = '你的网站名称'; // 你的短信签名
        private $templateCode = 'SMS_123456789'; // 你的短信模板ID
        public function send($tel, $code) {
            // 这里是阿里云短信的API调用示例
            // 你需要先安装阿里云的SDK: composer require aliyuncs/aliyun-php-sdk-core
            // 或者使用 curl 直接调用 API
            // 为了简化,这里直接使用 curl 调用
            $params = [
                'PhoneNumbers' => $tel,
                'SignName'     => $this->signName,
                'TemplateCode' => $this->templateCode,
                'TemplateParam' => json_encode(['code' => $code, 'product' => '表单提交']),
            ];
            // 生成签名
            $accessKeySecret = $this->accessKeySecret;
            $stringToSign = "GET&%2F&" . urlencode(self::computeSignature($params, $accessKeySecret));
            $signature = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret, true));
            // 构建请求URL
            $url = 'https://dysmsapi.aliyuncs.com/?' . http_build_query([
                'AccessKeyId' => $this->accessKeyId,
                'Signature' => $signature,
                'SignatureMethod' => 'HMAC-SHA1',
                'SignatureVersion' => '1.0',
                'SignatureNonce' => uniqid(),
                'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
                'Action' => 'SendSms',
                'Version' => '2025-05-25',
                'RegionId' => 'cn-hangzhou', // 你的区域ID
                'PhoneNumbers' => $params['PhoneNumbers'],
                'SignName' => $params['SignName'],
                'TemplateCode' => $params['TemplateCode'],
                'TemplateParam' => $params['TemplateParam'],
            ]);
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $response = curl_exec($ch);
            curl_close($ch);
            $result = json_decode($response, true);
            if (isset($result['Code']) && $result['Code'] == 'OK') {
                return ['code' => 200, 'msg' => '发送成功'];
            } else {
                return ['code' => 500, 'msg' => $result['Message'] ?? '发送失败'];
            }
        }
        // 计算签名的辅助函数
        private static function computeSignature($parameters, $accessKeySecret) {
            ksort($parameters);
            $stringToSign = '';
            foreach ($parameters as $k => $v) {
                if ($v === '' || is_null($v)) continue;
                $stringToSign .= '&' . self::percentEncode($k) . '=' . self::percentEncode($v);
            }
            return substr($stringToSign, 1);
        }
        private static function percentEncode($str) {
            $res = urlencode($str);
            $res = preg_replace('/\+/', '%20', $res);
            $res = preg_replace('/\*/', '%2A', $res);
            $res = preg_replace('/%7E/', '~', $res);
            return $res;
        }
    }
  2. 修改 plus/diy.php 文件

    • 在文件开头引入你的短信发送类。
    • 找到处理 action=post 的代码块,在其中加入验证码验证逻辑。
    • 在文件末尾,if($dsql->Execute('me',$query)){...} 之前,添加一个处理 action=sendSms 的分支。
    // plus/diy.php 修改部分
    // 在文件最顶部引入
    require_once(dirname(__FILE__)."/../include/common.inc.php");
    require_once(DEDEINC.'/SmsSender.php'); // 引入短信发送类
    // ... (文件中间部分保持不变) ...
    // 在 if($diy->makeField($dede_fields)) 之前,添加以下代码块
    if ($action == 'sendSms') {
        header('Content-Type: application/json; charset=utf-8');
        $tel = isset($tel) ? trim($tel) : '';
        if (empty($tel) || !preg_match("/^1[3-9]\d{9}$/", $tel)) {
            exit(json_encode(['code' => 400, 'msg' => '手机号格式不正确']));
        }
        // 生成6位随机验证码
        $smsCode = rand(100000, 999999);
        // 将验证码存入 Session,并设置5分钟有效期
        $_SESSION['sms_code_' . $tel] = [
            'code' => $smsCode,
            'expire_time' => time() + 300 // 5分钟
        ];
        // 实例化并发送短信
        $smsSender = new SmsSender();
        $result = $smsSender->send($tel, $smsCode);
        exit(json_encode($result));
    }
    // ... (原有的表单处理逻辑) ...
    // 找到处理表单提交的部分,在插入数据库之前,加入验证码校验
    if($dsql->Execute('me',$query))
    {
        // 在这里加入验证码校验逻辑
        $tel = isset($tel) ? trim($tel) : '';
        $userCode = isset($sms_code) ? trim($sms_code) : '';
        if (empty($tel) || empty($userCode)) {
            showMsg('手机号和验证码不能为空', '-1');
            exit();
        }
        $sessionKey = 'sms_code_' . $tel;
        if (!isset($_SESSION[$sessionKey])) {
            showMsg('请先获取验证码', '-1');
            exit();
        }
        $sessionData = $_SESSION[$sessionKey];
        if ($sessionData['code'] != $userCode) {
            showMsg('验证码错误', '-1');
            exit();
        }
        if (time() > $sessionData['expire_time']) {
            showMsg('验证码已过期,请重新获取', '-1');
            exit();
        }
        // 验证通过,删除已使用的验证码
        unset($_SESSION[$sessionKey]);
        // 验证码校验通过,继续执行原有逻辑
        $id = $dsql->GetLastID();
        if($diy->public == 1)
        {
            $diy->addvote();
        }
        $bkmsg = '发布成功!';
    }
    else
    {
        showmsg('发布失败!', '-1');
        exit();
    }
    // ... (文件结尾部分保持不变) ...

第四步:测试

  1. 上传文件:将你修改好的 plus/diy.php 和新创建的 include/SmsSender.php 上传到你的服务器。
  2. 清空缓存:登录 DedeCMS 后台,清空一下所有缓存。
  3. 访问表单页面:打开你的自定义表单页面。
  4. 测试流程
    • 输入一个有效的手机号,点击“获取验证码”。
    • 检查手机是否收到验证码。
    • 在表单中输入收到的验证码,填写其他信息,然后提交。
    • 检查是否提交成功,并成功添加到后台数据中。
    • 反向测试:输入错误的验证码,看是否会提示“验证码错误”。

注意事项和常见问题

  • Session 问题:确保你的服务器开启了 Session 功能,如果网站使用负载均衡或多服务器,需要使用共享 Session 存储(如 Redis)。
  • API 调用失败:检查 SmsSender.php 中的 accessKeyId, accessKeySecret, signName, templateCode 是否填写正确,查看服务器错误日志,了解具体的 API 错误信息。
  • 模板变量:短信模板中的变量(如 {1}, {2})必须和调用 API 时传入的 TemplateParam 数组中的键名对应,模板是 【验证码】{1}...TemplateParam 应该是 ['code' => $smsCode]
  • 防刷机制:为了防止恶意用户频繁获取验证码,你可以在 sendSms 逻辑中加入频率限制,例如同一个手机号每分钟只能请求一次。
  • HTTPS:短信 API 调用强烈建议使用 HTTPS,确保数据传输安全。

这个指南涵盖了从零到一集成短信验证码的全过程,虽然代码量稍多,但每一步的逻辑都很清晰,请根据你的实际情况(特别是短信服务商)进行调整。

-- 展开阅读全文 --
头像
织梦CMS模型下载地址在哪里?
« 上一篇 02-10
Eclipse C语言环境如何配置与使用?
下一篇 » 02-10

相关文章

取消
微信二维码
支付宝二维码

目录[+]