如何修复多账户登录时仅识别首行的问题

2026-01-28 00:00:00 作者:花韻仙語

本文详解 codeigniter 中基于文本文件的用户认证逻辑缺陷,重点解决因 `explode("\n")` 后未正确遍历所有行而导致的“仅能登录第一行账号”问题,并提供安全、健壮的登录验证重构方案。

在使用纯文本文件(如 #/config.txt)存储用户凭证的简易认证系统中,一个常见但隐蔽的逻辑错误会导致只有第一行注册账号可成功登录,后续账号始终提示“Account is not registered!”。根本原因并非 explode("\n") 失效,而是登录逻辑中 else 分支被错误地置于 foreach 循环内部——只要当前遍历的行 nis 不匹配表单提交值,就立即触发失败跳转,根本无法继续检查后续行。

? 问题定位:循环内过早终止

原始 _login() 方法中,关键错误在于:

foreach ($contents as $values) {
    // ... 解析 $nis, $password ...
    if ($nis == $_POST['nis']) {
        // ✅ 匹配成功分支(含密码校验)
    } else {
        // ❌ 错误!此处会为每一行不匹配都执行一次
        $this->session->set_flashdata('message', 'Account is not registered!');
        redirect('Auth'); // ⚠️ 第一行不匹配就跳走,永远到不了第二行!
    }
}

例如文件内容为:

12345,John,pass123
67890,Jane,pass456

当用户输入 nis=67890 时,循环首次取到 "12345,John,pass123" → $nis === '12345' ≠ '67890' → 立即执行 else 并重定向,第二行根本不会被读取。

✅ 正确解法:将“未找到”逻辑移出循环

只需将失败提示和跳转移至 foreach 之后,确保完整遍历所有行后仍未匹配才判定为未注册

private function _login()
{
    if (isset($_POST['login'])) {
        $data = file_get_contents("#/config.txt");
        // 使用 FILE_IGNORE_NEW_LINES 避免末尾空行干扰
        $lines = array_filter(array_map('trim', explode("\n", $data)), 'strlen');

        $found = false;
        foreach ($lines as $line) {
            $parts = str_getcsv($line); // ✨ 更安全:自动处理含逗号的姓名(如 "O'Connor, Jane")
            if (count($parts) < 3) continue; // 跳过格式异常行

            [$nis, $name, $password] = $parts;

            if ($nis === $_POST['nis']) {
                $found = true;
                if (hash_equals($password, $_POST['password'])) { // ✨ 防时序攻击
                    $this->session->set_userdata([
                        'nis' => $nis,
                        'name' => $name
                    ]);
                    redirect('User');
       

} else { $this->session->set_flashdata('message', 'Wrong password!' ); redirect('Auth'); } break; // 找到即退出,避免多余遍历 } } // ? 关键:循环结束后再判断是否找到 if (!$found) { $this->session->set_flashdata('message', 'Account is not registered!' ); redirect('Auth'); } } }

⚠️ 重要注意事项与增强建议

  • 空行与换行符处理:file_get_contents() 可能因编辑器差异引入 \r\n 或末尾空行,使用 array_filter(..., 'strlen') 清理无效行。
  • CSV 安全性:改用 str_getcsv() 替代 explode(","),可正确解析带英文逗号的用户名(如 "Smith, John"),避免字段错位。
  • 密码安全:生产环境绝不可明文存储密码!应使用 password_hash() 存储,password_verify() 校验。
  • 性能与扩展性:文本文件方案仅适用于极低并发演示。真实项目请迁移至 MySQL/PostgreSQL 等数据库,并添加索引加速 nis 查询。
  • 文件路径安全:#/config.txt 是非标准路径,建议改为 FCPATH . 'assets/config/users.csv' 并确保 Web 目录不可直接访问该文件。

通过修正控制流结构并采纳上述加固措施,即可彻底解决多账户登录失效问题,同时为后续系统演进奠定更可靠的基础。

猜你喜欢

联络方式:

400 9058 355

邮箱:8955556@qq.com

Q Q:8955556

微信二维码
在线咨询 拨打电话

电话

400 9058 355

微信二维码

微信二维码