首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >医药电商|药店商城小程序管理后台 常驻图形验证码 + 滑块验证 + 超次锁定

医药电商|药店商城小程序管理后台 常驻图形验证码 + 滑块验证 + 超次锁定

原创
作者头像
元岳科技
发布于 2026-10-26 16:32:25
发布于 2026-10-26 16:32:25
1200
举报
文章被收录于专栏:小程序搭建小程序搭建

管理后台登录是医药电商系统的核心入口,一旦管理员账号被暴力破解,商品、订单、资质等敏感数据将面临严重风险。本文记录我们在后台登录模块中落地的三层防护方案:常驻图形验证码 + 失败触发滑块 + 账号/IP 双维度锁定,重点分享几个关键的安全设计决策。

一、整体防护分层

1,登录接口的安全校验按成本从低到高依次执行:

2,锁定状态前置判断:账号或 IP 已被锁定,直接拒绝;

3,图形验证码常驻校验:每次登录必填,阻断自动化脚本;

4,滑块验证条件触发:连续失败达到阈值后强制要求;

5,账号密码核验:最后才进入核心认证逻辑。

把高拦截率、低成本的校验放前面,既提升安全性,也减少无效计算。核心流程代码如下:

代码语言:txt
复制
public function login()
{
    [$account, $password, $captchaVerification, $imgcode] =
        $this->request->postMore(['account', 'pwd', 'captchaVerification', 'imgcode']);

    // 1. 前置锁定校验(账号 + IP 任一命中即拒绝)
    if ($this->isLocked($account)) {
        return app('json')->fail('登录失败次数过多,请15分钟后再试');
    }

    // 2. 图形验证码常驻校验
    if (!app()->make(Captcha::class)->check($imgcode)) {
        return app('json')->fail('验证码错误');
    }

    // 3. 滑块验证(失败触发)
    if ($captchaVerification && !$this->checkSlide($captchaVerification)) {
        return app('json')->fail('滑块验证失败', ['login_captcha' => 1]);
    }

    // 4. 账号密码核验
    $result = $this->services->login($account, $password, 'admin');
    if (!$result) {
        $failCount = $this->recordFail($account); // 记录失败次数
        $needSlide = $failCount >= 2 ? 1 : 0;     // 失败2次后触发滑块
        return app('json')->fail('账号或密码错误', ['login_captcha' => $needSlide]);
    }

    $this->clearFail($account); // 登录成功,清除失败计数
    return app('json')->success($result);
}

二、三个关键设计决策

1. 验证码失败不计入登录失败次数

这是整个方案里最容易踩坑的点。如果验证码错误也计入失败次数,攻击者可以故意输错验证码来消耗失败额度,无需知道密码就能把管理员账号锁死——典型的账号锁定型拒绝服务攻击。

因此我们只把"验证码正确,但账号或密码错误"计为一次有效失败:

代码语言:txt
复制
// 图形验证码校验失败 → 直接返回,不调用 recordFail()
if (!app()->make(Captcha::class)->check($imgcode)) {
    return app('json')->fail('验证码错误');
}

// 只有账号密码校验失败才计入
if (!$result) {
    $failCount = $this->recordFail($account);
}

2. IP 阈值远高于账号阈值

账号维度设为 5 次,IP 维度设为 50 次。企业环境中多个管理员可能共用一个公网 IP,IP 阈值过低会导致"一个人输错几次,全办公室被锁"的误伤。账号做精准防护,IP 做兜底防护,各司其职。

代码语言:txt
复制
const LOGIN_FAIL_MAX      = 5;   // 账号维度:精准锁定
const LOGIN_FAIL_IP_MAX   = 50;  // IP 维度:兜底防护,防误伤
const LOGIN_FAIL_LOCK_TIME = 900; // 锁定15分钟,到期自动解锁

3. 登录成功后只清账号计数,不清 IP 计数

如果登录成功就清除 IP 计数,攻击者可以通过"先暴力破解一批账号,再用正确密码登录其中一个"来重置 IP 防护。保留 IP 计数,堵住这条旁路。

代码语言:txt
复制
private function clearFail(string $account): void
{
    CacheService::delete('login_fail_admin_' . md5($account));
    // 注意:不清除 IP 维度计数,防止被利用来重置兜底防护
}

三、前后端协同

后端返回数据中携带 login_captcha 字段,前端据此决定是否弹出滑块:

login_captcha 值

前端行为

0

不弹滑块,仅提示错误

1

弹出滑块验证,用户必须完成才能再次提交

四、小结

防护维度

策略

核心收益

图形验证码

常驻必填

阻断自动化脚本

滑块验证

失败2次触发

区分人机,不打扰正常用户

账号锁定

5次/15分钟

精准防护暴力破解

IP 锁定

50次/15分钟

兜底防护,防误伤

真正的安全往往藏在那些"看起来多此一举"的细节里——验证码失败不计数的设计,恰恰是防住最容易被忽视的攻击面。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档