这是我的代码:
<?php
$pass = $_GET["pass"];
$user = $_GET["user"];
$next = false;
$file = fopen("info.txt", "r") or die("Something went wrong.");
// Output one line until end-of-file
while(!feof($file)) {
if ($next == true and $pass === fgets($file)){
echo "true";
$next = false;
} else {
echo "false" . "<br>";
$next = false;
}
if (fgets($file) == $user) {
$next = true;
}
}
fclose($file);
?>
这是info.txt
ch1ck3n
kodero1029
注意,这只是一个虚构的密码
例如,我们转到包含此代码的我的网站,https://ch1ck3n.com/login/auth/auth.php?user=ch1ck3n&pass=kodero1029
并且它打印假两次。我正在使用php和一个简单的txt文档制作一个登录系统。php代码逐个读取txt文件行,如果一行与用户名匹配,则意味着密码在下一行。但如果你看到了,去网站,它会打印两次假。CCD_ 2变量用于指示下一行是密码。
怎么了
您的问题是因为:
if (fgets($file) == $user) {
$next = true;
}
为什么这是错误的
这是$next为真的唯一方法,但您有$user = $_GET["user"] //ch1ck3n
,但如果您查看手册,它会指出:
fgets:
返回从句柄指向的文件读取的长度不超过1字节的字符串。如果文件指针中没有更多的数据可读取,则返回FALSE。
另请参阅:
读取长度为-1字节或换行符(包含在返回值中(时,读取结束
(我的括号(
因此,fgets的返回值是一个包含行尾的字符串,并将其与没有行尾的文本字符串ch1ck3n
进行比较。因此,$next
永远不会为true,因此对于文件的每一行,if
/else
语句都将返回false选项。
解决方案:
从字符串中提取换行符:
if (trim(fgets($file)) === $user) {
$next = true;
}
对于您使用fgets
的所有场合,都需要执行相同的操作。
安全注意事项:
正如评论中所提到的,你处理这个问题的方法re:security绝对是不正确的做法。您应该使用POST请求、数据库引用或SESSION cookie来安全地将凭据数据与脚本关联。
不要在URL中发送敏感信息,因为无论是否使用https:Link
,这都是不安全的
Felipe Duarte 评论
循环的每次迭代读取两行。因为你只有两行(也许是三行?(,这意味着在一次迭代中你就完成了。这样做:
<?php
$pass = $_GET["pass"];
$user = $_GET["user"];
$next = false;
$file = fopen("info.txt", "r") or die("Something went wrong.");
// Output one line until end-of-file
while(!feof($file)) {
$line = rtrim(fgets($file)); //Newline is included in the fgets result
if ($next == true && $pass === $line){
echo "true";
$next = false;
} else {
echo "false" . "<br>";
$next = false;
}
if ($line === $user) {
$next = true;
}
}
fclose($file);
两次都为false的原因(可能(是因为文件末尾可能有一行空行。