xnx_adminlogin 后台登录邮箱验证
为 Xiuno BBS X(XIUNOX)后台登录增加邮箱验证码双因素校验。启用后,管理员登录 /admin/ 需通过「密码 + 邮箱验证码」双重验证,即使密码泄露,攻击者也无法进入后台。
版本:1.0.2
依赖:XIUNOX 1.1+,系统 SMTP 邮件服务(后台 → 设置 → 邮件服务)
兼容:Redis / 文件缓存等 Xiuno 标准缓存驱动
功能特性
双因素校验:后台登录页密码框下方动态插入「邮箱验证码」输入框与「获取验证码」按钮,验证码输入后回车即可提交登录
验证码有效期:6 位纯数字随机码,默认 5 分钟有效(可配置 1-15 分钟)
IP 发送频率限制:同一 IP 发送验证码默认间隔 60 秒(可配置 30-300 秒),防恶意刷取邮件
错误锁定:同一管理员连续输错验证码达阈值(默认 5 次,可配置 3-10 次)锁定验证环节(默认 15 分钟,可配置 5-60 分钟),锁定期间完全冻结发码与校验,提示带剩余时间
锁定作废旧码:触发锁定时同步作废已发送的验证码
审计日志:记录每次发码与登录校验操作(IP、账号、时间、结果),支持事后安全审计
邮件内容:含验证码、有效期限、本次登录 IP,模板可自定义
多语言:简体中文 / 繁体中文 / English
图形验证码叠加共存:不改动系统自带图形验证码(密码错 3 次后出现)逻辑,两者叠加校验
安装与启用
将
xnx_adminlogin目录放入站点plugin/下后台 → 插件管理 → 找到「后台登录邮箱验证」→ 安装并启用
进入插件设置页:
若顶部出现「邮件服务未配置」告警,请先到 后台 → 设置 → 邮件服务 配置 SMTP
确认管理员账号已在前台绑定邮箱(未绑定时发码会提示先绑定)
开启「启用邮箱验证码」开关并保存
插件默认安装后为关闭状态(enabled=0),不会立即锁死后台;请确认 SMTP 可用后再开启。
配置项说明
配置项 | 说明 | 默认值 | 范围 |
|---|---|---|---|
启用邮箱验证码 | 全局开关,关闭后恢复仅密码登录 | 关闭 | - |
验证码有效期 | 验证码存活时长 | 5 分钟 | 1-15 分钟 |
发送间隔 | 同一 IP 两次发码最小间隔 | 60 秒 | 30-300 秒 |
错误锁定阈值 | 连续输错多少次触发锁定 | 5 次 | 3-10 次 |
锁定时长 | 触发锁定后冻结时长 | 15 分钟 | 5-60 分钟 |
邮件标题 | 邮件主题模板 | {sitename} 后台登录验证码 | 支持占位符 |
邮件正文 | 邮件内容 HTML 模板 | 见设置页 | 支持占位符 |
邮件模板占位符
占位符 | 含义 |
|---|---|
| 6 位验证码 |
| 有效期(分钟) |
| 本次登录 IP 地址 |
| 站点名称 |
| 管理员用户名 |
设置页提供实时预览框,编辑模板即可查看渲染效果。
使用流程
访问
/admin/,输入管理员账号密码点击密码框下方「获取验证码」→ 系统校验密码正确后发送验证码至管理员绑定邮箱
查收邮件(含验证码、有效期限、登录 IP),在验证码框输入
回车或点击登录 → 双重校验通过后进入后台
按钮倒计时期间不可重复发送;验证码输错计入错误计数,达阈值锁定并提示剩余时间。
安全机制
服务端强制校验:拦截逻辑位于编译期注入的后台登录 POST 分支,与前端渲染无关——隐藏或删除页面上的验证码输入框无法绕过
回滚防半登录态:验证码校验失败时先回滚
$_SESSION['uid']与 admin_token,再返回错误防时序攻击:验证码比对使用
hash_equalsCSRF 防护:发码 Ajax 与设置保存均校验 CSRF token
一次性验证码:校验通过立即删除缓存,不可重放
锁定冻结:锁定期间发码与登录校验完全拒绝;触发锁定时旧验证码同步作废
审计日志
位置:plugin/xnx_adminlogin/log/YYYYMM/xnx_adminlogin_audit.php(<?php exit; 头防 web 直接读取)
每行格式:
[2026-08-21 13:00:00] ip=1.2.3.4 uid=1 user=admin action=send result=ok
[2026-08-21 13:02:00] ip=1.2.3.4 uid=1 user=admin action=verify result=error
action 取值:send(发码)/ verify(登录校验);result 取值:ok / password_error / required / expired / error / locked / fail 等。
目录结构
xnx_adminlogin/
├── conf.json # 插件元信息与 hooks_rank
├── install.php # 安装:默认配置 + log 目录
├── uninstall.php # 卸载:清配置/缓存/日志
├── setting.php # 设置保存(CSRF + clamp 范围校验)
├── setting.htm # 设置页模板(SMTP 告警 + 模板预览)
├── hook/
│ ├── admin_index_login_get_post.php # Ajax 发码接口(挂 index-login 路由内)
│ ├── admin_index_login_post_end.php # 登录二次校验拦截(失败回滚 session/token)
│ ├── admin_index_login_end.htm # 登录页注入 I18N/CFG/JS
│ ├── model_inc_file.php # Service 注册到编译链
│ └── lang_*_bbs.php # 三语语言键
├── service/
│ ├── MailCodeService.php # 发码主流程/验证码校验/邮件渲染
│ └── XnxAdminloginSecurityService.php # 锁定/计数/IP 频率/审计日志
├── static/js/admin_login.js # 原生 JS:动态插入输入框/倒计时/Ajax
├── lang/{zh-cn,zh-tw,en-us}/bbs_admin.php
└── log/YYYYMM/xnx_adminlogin_audit.php
常见问题
Q:已配置 SMTP,设置页仍提示「邮件服务未配置」? A:v1.0.1 已修复(邮件函数按需加载)。若仍出现,确认 conf/smtp.conf.php 中 host 与 user 均非空,并在插件管理页升级到最新版本。
Q:禁用浏览器 JavaScript 后还能登录后台吗? A:不能。验证码输入区依赖 JS 渲染,但服务端校验始终强制生效——这是双因素安全的设计要求,无 JS 放行的后门即攻击者的绕过路径。
Q:管理员未绑定邮箱怎么办? A:点击「获取验证码」时会提示先在前台个人中心绑定邮箱,绑定后即可使用。
Q:忘记是否开启、被锁定了怎么办? A:锁定最长 60 分钟后自动解除;也可由另一名超级管理员在插件设置页临时关闭「启用邮箱验证码」恢复仅密码登录。
更新日志
1.0.2 安全加固:登录校验增加锁定前置检查(锁定期完全冻结);触发锁定时作废旧验证码
1.0.1 修复:已配置 SMTP 仍提示未配置(邮件函数未按需加载)
1.0.0 初始版本


版本:v1.0.2
适用版本:1.1
开发者:贰先生



