电话
400 9058 355
本文详解 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');
}
}
}通过修正控制流结构并采纳上述加固措施,即可彻底解决多账户登录失效问题,同时为后续系统演进奠定更可靠的基础。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...