dede免登录提交订单如何实现安全验证?

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

这是一个非常常见的需求,尤其是在移动端或者追求极致用户体验的场景下,用户无需注册或登录,直接填写收货信息和订单备注即可完成下单。

dede免登录提交订单
(图片来源网络,侵删)

核心思路

免登录提交订单的本质是 “临时创建用户”,流程如下:

  1. 用户进入提交订单页面:系统判断用户是否登录,如果未登录,则显示一个简化的注册/登录表单,或者直接显示一个纯订单信息填写表单。
  2. 填写订单信息:用户填写收货人、电话、地址、商品信息等。
  3. 创建临时用户:在后端处理逻辑中,系统会根据用户填写的手机号或邮箱,自动在 dede_member 表中创建一个新用户,为了区分,这个用户的 mtype 字段可以设置为一个特殊值('temp'),useridpwd 字段可以设置为手机号或邮箱的哈希值,或者一个随机字符串。
  4. 关联订单与临时用户:在创建订单时,将这个临时用户的 uid 关联到订单记录中。
  5. 完成下单:订单创建成功后,可以提示用户“下单成功,请使用手机号登录查看订单详情”,并引导其完善个人信息或进行支付。

详细实现步骤

我们将分步实现这个功能,主要涉及修改模板文件和修改PHP处理文件。

第一步:准备订单提交页面模板

订单提交页面是 plus/cartridge.php,我们需要修改这个文件,使其在用户未登录时也能显示订单信息表单。

  1. 修改 plus/cartridge.php 文件

    dede免登录提交订单
    (图片来源网络,侵删)

    在文件开头,找到检查登录状态的代码,并将其注释掉或修改,在包含订单表单的模板之前,加入我们自己的逻辑。

    <?php
    require_once(dirname(__FILE__)."/../include/config_base.php");
    require_once(DEDEINC."/membermodel.cls.php");
    require_once(DEDEINC.'/shopcar.class.php');
    require_once(DEDEINC.'/dedetemplate.class.php');
    // 检查用户是否登录,如果未登录,我们不直接跳转,而是继续执行下面的逻辑
    // if($cfg_ml->IsLogin()) {
    //     // 已登录用户逻辑...
    // } else {
    //     // 未登录用户逻辑...
    // }
    $cart = new MemberShopsCart();
    if(empty($cart->fields)) {
        ShowMsg("您的购物车是空的,请先去购物!", 'javascript:;');
        exit();
    }
    // 获取收货地址列表(这里可以修改,只获取已登录用户的地址,或者显示一个公共地址列表)
    // $addrs = $cart->GetAddressList();
    $dsql = new DedeSql(false);
    $row = $dsql->GetOne("SELECT * FROM #@shop_config");
    unset($dsql);
    $templet = $cfg_basedir.$cfg_templets_dir."/plus/cartridge.htm";
    $dtp = new DedeTemplate();
    $dtp->LoadTemplate($templet);
    $dtp->Display();
    ?>
  2. 修改订单提交模板 templets/plus/cartridge.htm

    在这个模板中,我们需要确保即使没有登录,也能正常显示订单信息,关键在于传递 mid (用户ID) 给后续的处理页面。

    在模板中找到处理订单的表单,确保它存在并正确。

    dede免登录提交订单
    (图片来源网络,侵删)
    <form name='orderform' action='cartridge.php?dopost=send' method='post'>
        <!-- 这里是购物车商品列表 -->
        <!-- ... -->
        <!-- 收货人信息 -->
        <table width="100%" border="0" cellspacing="0" cellpadding="0">
            <tr>
                <td height="30" colspan="2" style="font-weight:bold;">收货人信息</td>
            </tr>
            <tr>
                <td width="20%" height="28">收货人姓名:</td>
                <td>
                    <input type='text' name='usernames' id='usernames' size='30' class='intxt' style='width:250px' />
                </td>
            </tr>
            <tr>
                <td height="28">联系电话:</td>
                <td>
                    <input type='text' name='user tel' id='user tel' size='30' class='intxt' style='width:250px' />
                </td>
            </tr>
            <tr>
                <td height="28">电子邮箱:</td>
                <td>
                    <input type='text' name='email' id='email' size='30' class='intxt' style='width:250px' />
                </td>
            </tr>
            <tr>
                <td height="28">收货地址:</td>
                <td>
                    <textarea name='address' id='address' rows='3' cols='60' style='width:400px;'></textarea>
                </td>
            </tr>
            <tr>
                <td height="28">订单备注:</td>
                <td>
                    <textarea name='message' id='message' rows='3' cols='60' style='width:400px;'></textarea>
                </td>
            </tr>
        </table>
        <!-- 关键:传递用户ID,如果未登录,则留空,由后端处理 -->
        <input type="hidden" name="mid" value="<?php echo $cfg_ml->M_ID; ?>" />
        <div style="margin-top:20px; text-align:center;">
            <button type="submit" name="submit" class="btn btn-primary">提交订单</button>
        </div>
    </form>

第二步:修改订单处理逻辑

这是最关键的一步,我们需要修改 plus/cartridge.php 中处理 dopost=send 的部分。

  1. plus/cartridge.php 中找到 send 处理分支

    这个分支通常在文件末尾,我们将重写这部分代码。

  2. 编写核心处理逻辑

    逻辑是:检查 mid 是否为空,如果为空,则根据手机号或邮箱创建一个临时用户,然后获取其 uid,再继续创建订单。

    // ... 文件前面的代码 ...
    // 处理订单提交
    if($dopost == 'send')
    {
        // 1. 获取表单数据
        $usernames = trim($_POST['usernames']);
        $usertel = trim($_POST['usertel']);
        $email = trim($_POST['email']);
        $address = trim($_POST['address']);
        $message = trim($_POST['message']);
        $mid = isset($_POST['mid']) ? intval($_POST['mid']) : 0;
        // 基本验证
        if(empty($usernames) || empty($usertel) || empty($address)) {
            ShowMsg("请填写完整的收货人信息!", '-1');
            exit();
        }
        // 2. 核心逻辑:如果用户未登录,则创建临时用户
        if(empty($mid) || !$cfg_ml->IsLogin())
        {
            // 检查手机号是否已注册
            $dsql->SetQuery("SELECT uid FROM `#@__member` WHERE mobilephone = '$usertel' OR userid = '$usertel'");
            $dsql->Execute();
            if($row = $dsql->GetArray())
            {
                // 如果手机号已存在,直接使用该用户
                $mid = $row['uid'];
            }
            else
            {
                // 手机号不存在,创建一个新用户
                $pwd = md5($usertel); // 密码设为手机号MD5值,用户可后续修改
                $uname = $usertel;    // 用户名也设为手机号
                $mtype = 'temp';      // 标记为临时用户
                $inQuery = "INSERT INTO `#@__member`(`mtype`, `userid`, `pwd`, `uname`, `email`, `mobilephone`, `jointime`, `joinip`) 
                            VALUES ('$mtype', '$uname', '$pwd', '$usernames', '$email', '$usertel', '".time()."', '".GetIP()."')";
                $dsql->ExecuteNoneQuery($inQuery);
                if($dsql->GetErrorNum() > 0)
                {
                    ShowMsg("创建用户失败,请联系管理员!", '-1');
                    exit();
                }
                $mid = $dsql->GetLastID(); // 获取新创建用户的ID
            }
        }
        // 3. 创建订单 (这部分代码可以参考原DedeCMS的订单创建逻辑,通常在member/shops_action.php等文件里)
        // 这里简化了订单创建过程,你需要根据你的实际订单表结构和创建逻辑来完善
        $money = $cart->GetPriceCount(); // 获取订单总金额
        $order_sn = 'DD'.date('YmdHis').rand(1000, 9999); // 生成唯一订单号
        $orderQuery = "INSERT INTO `#@__member_shops_order`(`order_sn`, `mid`, `usernames`, `email`, `tel`, `address`, `money`, `dtime`, `ptotal`, `message`) 
                       VALUES ('$order_sn', '$mid', '$usernames', '$email', '$usertel', '$address', '$money', '".time()."', '0', '$message')";
        $dsql->ExecuteNoneQuery($orderQuery);
        if($dsql->GetErrorNum() > 0)
        {
            ShowMsg("创建订单失败,请联系管理员!", '-1');
            exit();
        }
        $oid = $dsql->GetLastID();
        // 4. 清空购物车
        $cart->ClearCart();
        // 5. 跳转到支付或成功页面
        ShowMsg("订单提交成功!订单号:".$order_sn.",请使用手机号 ".$usertel." 登录并支付。", '/member/index.php?uid='.$mid); // 跳转到用户中心
        exit();
    }

第三步:安全性与用户体验优化

  1. 安全性

    • 数据过滤:所有从表单获取的数据($_POST)都必须经过 trim()htmlspecialchars() 等函数处理,防止XSS攻击。
    • SQL注入:DedeCMS 的 $dsql 类已经做了基本的防注入处理,但使用 SetQuery 时,如果涉及变量拼接,最好使用 $dsql->SetQuery("SELECT ... WHERE id = {$id}") 这种方式,让Dede自行处理。
    • 密码安全:临时用户的密码使用了 md5 加密,虽然 md5 已不推荐用于密码存储,但对于临时用户来说,这已经足够,你可以使用 password_hashpassword_verify 来增强安全性,但这需要修改会员登录验证逻辑。
  2. 用户体验

    • 提示信息:下单成功后,明确告知用户订单号,并告知其如何登录(使用手机号/邮箱)。
    • 自动登录:在创建临时用户后,可以尝试模拟登录,让用户直接进入登录状态,这需要调用 cfg_ml->PutLoginInfo() 等方法,逻辑稍复杂,但体验更好。
    • 支付集成:订单创建成功后,应立即跳转到支付页面(如支付宝、微信支付),而不是仅仅显示一个成功消息,这需要你集成相应的支付SDK或调用DedeCMS自带的支付接口。

实现 DedeCMS 免登录提交订单的核心步骤可以概括为:

  1. 修改模板:让订单提交页面在未登录时也能显示,并传递一个空的 mid
  2. 修改PHP逻辑:在订单处理的后端代码中,判断 mid 是否为空,如果为空,则根据用户填写的手机号/邮箱自动创建一个 mtype='temp' 的临时用户,并获取其 uid
  3. 关联订单:将这个新用户的 uid 作为 mid 存入订单表中,完成订单与用户的关联。
  4. 优化与安全:完善数据验证、错误处理,并考虑如何提升用户体验(如提示登录、引导支付)。

这个方案提供了一个完整的实现思路,你可以根据自己网站的具体情况进行调整和扩展。

-- 展开阅读全文 --
头像
浙大城市学院C语言上机,怎么高效备考拿高分?
« 上一篇 今天
C语言字符串如何高效插入另一字符串?
下一篇 » 今天

相关文章

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

目录[+]