活力39282
在线时间13640 小时
阅读权限200
管理员
自由的灵魂
- 积分
- 107434
- 主题
- 5630
- 回帖
- 26661
- 注册时间
- 2003-4-10
- 最后登录
- 2026-10-2
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
1、问题缘起
论坛存在可疑用户注册后等待数天才发帖的情况,部分账号注册 IP 与后续登录 IP 跨越不同国家或地区。现有 Discuz! 系统仅在后台开启异地登录验证码功能,无法主动通知管理员,导致异常登录行为难以及时发现和处理。
探讨过程中发现的相关问题:
| 问题 | 解决方案 | | 首次登录用户无「上次登录IP」记录 | 改用注册 IP 作为参照对象 | | 香港、台湾被识别为「中国」,无法跨区判断 | 自定义地区标准化函数,独立识别 | | 首次登录邮件显示时间 1970-01-01 | 改用注册时间作为参照时间 | | 邮件为纯文本格式,信息拥挤 | 改为 HTML 表格,三栏对照显示 |
2、解决方案
(1)简要技术分析:
在 Discuz! 登录验证流程中,利用已有的异地登录判断逻辑(比较本次登录 IP 与上次登录 IP 的归属地区),当地区发生变化时,通过邮件队列异步发送通知给管理员;首次登录用户则使用注册 IP 作为参照。
(2)修改文件列表:
| 操作 | 文件路径 | | 修改 | /source/class/class_member.php |
(3)关键代码段:
地区标准化函数(将香港、台湾识别为独立地区):
- function custom_region($region) {
- if (strpos($region, '香港') !== false) return '香港';
- if (strpos($region, '台湾') !== false) return '台湾';
- if (strpos($region, '澳门') !== false) return '澳门';
- $spacePos = strpos($region, ' ');
- if ($spacePos !== false) return substr($region, 0, $spacePos);
- return $region;
- }
复制代码
异地登录判断与邮件发送(插入位置:异地登录验证码触发处):
- if ($lastRegion != $nowRegion) {
- // 首次登录改用注册IP作为参照
- if (empty($_G['member']['lastip']) || $lastFull == 'Invalid') {
- $registerIp = C::t('common_member_status')->fetch($_G['uid'])['regip'];
- if ($registerIp) {
- $registerFull = convertip($registerIp);
- $referenceRegion = custom_region($registerFull);
- $referenceFull = $registerFull;
- $referenceTime = $_G['member']['regdate'];
- }
- }
-
- if ($referenceRegion != $nowRegion) {
- // 发送HTML格式邮件,表格展示IP、地区、时间三栏对比
- sendmail($admin_email, $subject, $message);
- $seccodecheck = true; // 保留原验证码逻辑
- }
- }
复制代码
邮件表格结构:
| 类型 | IP地址 | 归属地区 | 时间 | | 上次登录/注册地区 | xxx.xxx.xxx.xxx | 美国 | 2026-05-30 10:00:00 | | 本次登录 | xxx.xxx.xxx.xxx | 台湾 | 2026-06-05 07:02:35 |
3、最终实现效果
| 场景 | 是否触发邮件 | 参照对象 | | 上次登录地区 ≠ 本次登录地区 | ✅ | 上次登录 IP 地区 | | 首次登录 + 注册地区 ≠ 本次登录地区 | ✅ | 注册 IP 地区 | | 首次登录 + 注册地区 = 本次登录地区 | ❌ | 不触发 | | 地区相同(如北京 → 上海) | ❌ | 不触发 | | 中国 → 香港/台湾 | ✅ | 独立地区识别 |
邮件显示效果:
- HTML 格式,卡片样式
- 用户名可点击,跳转至用户个人资料页
- IP、地区、时间三栏对照,上下结构清晰对比
- 区分「上次登录地区」与「注册地区」两种对照类型
4、重要技术沉淀
需更新到固化摘要:
- 十六、跨国/跨地区登录邮件提醒(2026-06-05)
- 功能:用户异地登录时,自动发送邮件通知管理员
- 涉及文件:source/class/class_member.php
- 触发条件:本次登录地区与上次登录地区(或注册地区)不同
- 地区识别:香港、台湾、澳门独立,其他国家按首段识别
- 首次登录处理:无上次登录记录时,使用注册IP作为参照
- 邮件格式:HTML表格,IP、地区、时间三栏对照
- 管理员邮箱:admin@dianbo.org
复制代码
踩坑点:
| 踩坑 | 正确做法 | | 首次登录时上次登录IP为空,convertip() 返回 Invalid | 改用注册 IP 作为参照 | | 香港、台湾地区被识别为「中国」,无法区分 | 自定义函数提取关键词独立识别 | | 首次登录邮件参照时间为 1970-01-01 | 从 common_member 表取 regdate | | 纯文本邮件信息拥挤不易读 | 改为 HTML 表格,三栏对照 |
5、进一步优化可能性
- 频率限制:同一用户短时间内多次异地登录,仅首次发送邮件,避免轰炸
- 白名单:允许设置信任地区(如国内切换省份不通知)
- 管理面板开关:后台可配置是否开启此功能及管理员邮箱
- 用户自通知:同时向用户本人发送提醒,告知账号可能被他人登录
|
|