我已经尝试为我的登录脚本设置自动登录功能已经有两个晚上了。
我在users表中有一个名为session_key varchar(255)的字段,其中存储了使用MD5散列的用户IP地址。
如果设置了cookie,则会设置会话变量,如果未设置,则会出现一个表单。
当他们登录时,如果他们选中了名为autologin的复选框,它将在字段session_key中存储他们的MD5哈希IP地址。
现在,如果他们关闭浏览器并返回,我会检查他们的cookie是否等于数据库中的session_key。
这就是混乱的代码!我没想到实现自动登录功能会这么难……
session_start();
// see if the auto-login cookie exists, if so set sessions vars
if (isset($_COOKIE['autologin'])) {
$user=mysql_query("select * from users where session_key = $_COOKIE[autologin]");
$row3=mysql_fetch_assoc($user);
if ($_COOKIE['autologin'] == $row3['session_key']) {
$_SESSION['id'] = $row3['id'];
header("Location: login.php");
}
}
// User pressed "Login"
if (count($_POST)) {
$result = mysql_query("SELECT id FROM users
WHERE username = '".mysql_real_escape_string($_POST['username'])."'
AND password = '".mysql_real_escape_string($_POST['password'])."' ");
if (mysql_num_rows($result) == 0) {
$error = '<script>alert("Wrong username and/or password.\nTry again.") </script>';
} else {
$_SESSION['id'] = mysql_result($result, 0, 'id');
header("Location: login.php");
mysql_query("UPDATE users SET session_key = '".md5($_SERVER['REMOTE_ADDR'])."'");
setcookie("autologin", md5($_SERVER['REMOTE_ADDR']), time()+3600);
}
}
if (isset($_SESSION['id'])) {
exit('You are logged in!');
}
<form method="post">
<tr>
<td valign="top" width="95px"><b>Username:</b></td>
<td><input type="text" name="username" size="22" /></td>
</tr>
<tr>
<td valign="top"><b>Password:</b></td>
<td><input type="password" name="password" size="22" /></td>
</tr>
<tr>
<td valign="top"><b>Auto-login:</b></td>
<td><input type="checkbox" name="autologin" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Login" /></td>
</tr>
</form>这样安全吗?操作cookie容易吗?
Afaik,youtube都有这个功能--他们是怎么做到的?
我不能让它工作,有人能帮我吗?
发布于 2009-09-06 01:04:28
首先,不要将用户的字符串(包括cookie)插入到SQL中,而不先对其进行转义。
其次,会话密钥需要是唯一的,并且很难被猜到。看起来我要做的就是窃取别人的会话,只要知道他们的IP地址就行了。更糟糕的是,我可以通过与他们拥有相同的IP来意外地窃取他们的会话(如果我和他们在同一栋楼里,这种情况经常会发生)。
第三,你的缩进和你的花括号不匹配,所以很难弄清楚到底是怎么回事。
第四,这个"if ($_COOKIE['autologin'] == $row3['session_key'])"是多余的,因为您已经检查了它们匹配的SQL。
第五,在第5行,您的(未转义的)值周围没有引号,所以如果您的代码执行到了这一步,您应该会得到一个SQL语法错误。
我建议你制作简单得多的更小的代码片段,一次测试一个。例如,从设置cookie开始,然后测试该值是否通过。然后,只有在您得到工作之后,添加一些代码来检查数据库记录是否与您的cookie匹配。并确保将所有放入sql中的内容进行编码,因此,如果有人将他们的cookie设置为";drop database xxx“或其他任何值,您就不会完蛋。
发布于 2009-09-05 21:11:58
首先:
// User pressed "Login"
if (count($_POST)) {
$result = mysql_query("SELECT id FROM users
WHERE username = '".mysql_real_escape_string($_POST['username'])."'
AND password = '".mysql_real_escape_string($_POST['password'])."' ");
if (mysql_num_rows($result) == 0) {
$error = '<script>alert("Wrong username and/or password.\nTry again.") </script>';
} else {
$_SESSION['id'] = mysql_result($result, 0, 'id');
header("Location: login.php");
mysql_query("UPDATE users SET session_key = '".md5($_SERVER['REMOTE_ADDR'])."'");
setcookie("autologin", md5($_SERVER['REMOTE_ADDR']), time()+3600);
}
}在你写过的最后一节中:
header("Location: login.php");在通过头函数重定向用户之后,您正在更新数据库并设置cookie。因此,您的代码永远不会更新并设置cookie。将其更改为:
// User pressed "Login"
if (count($_POST)) {
$result = mysql_query("SELECT id FROM users
WHERE username = '".mysql_real_escape_string($_POST['username'])."'
AND password = '".mysql_real_escape_string($_POST['password'])."' ");
if (mysql_num_rows($result) == 0) {
$error = '<script>alert("Wrong username and/or password.\nTry again.") </script>';
} else {
$_SESSION['id'] = mysql_result($result, 0, 'id');
mysql_query("UPDATE users SET session_key = '".md5($_SERVER['REMOTE_ADDR'])."'");
setcookie("autologin", md5($_SERVER['REMOTE_ADDR']), time()+3600);
header("Location: login.php");
}
}发布于 2021-05-27 21:30:11
抱歉,但是涉及IP地址的整个方案都不能解决这个问题。你必须考虑使用便携式设备的人(世界上大多数人),以及使用动态IP地址的人(其他大多数人),这些人可以而且确实会在任何时候发生变化。
您可以尝试UID会话cookies,只将会话ID保存在浏览器cookies中,同时在用户数据库记录中保持连接状态。
为了集成设备依赖,通常使用来自请求头的浏览器字符串,并将其保存在用户记录中。
这可能是一个练习连接状态图的好机会。
对不起,我可能包括的任何代码将是语言和集成特定的,但我也使用我的用户I中的校验数字,以便我可以验证他们而不使用数据库。(另一个讨论的主题)
https://stackoverflow.com/questions/1384236
复制相似问题