使用cookie自动登录

时间:2009-09-05 20:49:47

标签: php cookies

我一直在努力为我的登录脚本制作一个自动登录功能2晚。

我的用户表中有一个名为session_key varchar(255)的字段,其中我将用户的IP地址存储在MD5中。

如果设置了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>&nbsp;</td>
<td><input type="submit" value="Login" /></td>
</tr>

</form>
这是否安全?操纵cookie很容易吗?

Afaik,youtube体育这个功能 - 他们是如何做到的?

我不能让这个工作,有人可以帮助我吗?

3 个答案:

答案 0 :(得分:2)

首先,不要将用户的字符串(包括cookie)粘贴到SQL中,而不要先将其转义。

其次,会话密钥需要是唯一的,很难猜测。看起来我要偷走某个人的会话就是知道他们的IP地址。更糟糕的是,我可以通过拥有与他们相同的IP来偶然窃取他们的会话(如果我和他们在同一个建筑物中,情况经常如此)。

第三,你的缩进与大括号不符,因此很难弄清楚发生了什么。

第四,这个"if ($_COOKIE['autologin'] == $row3['session_key'])"是多余的,因为你已经在SQL中检查过它们匹配。

第五,在你的第5行,你的(未转义)值没有引号,所以如果你的代码执行到了这一点,你应该得到一个SQL语法错误。

我建议你制作更简单的小代码片段,一次测试一个。例如,从设置cookie开始,并测试值是否通过。然后,只有在您开始工作之后,添加一些代码以检查数据库记录是否与您的cookie匹配。并确保编码你在sql中放置的所有内容,所以如果有人将他们的cookie设置为“;删除数据库xxx”或其他什么,你就不会搞砸了。

答案 1 :(得分:1)

首先:

    // 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");

}

}

答案 2 :(得分:1)

抱歉,涉及 IP 地址的整个架构不会削减它。您必须考虑使用便携式设备的用户(世界上大部分地区),以及拥有动态 IP 地址的用户(其余大部分地区),这些用户可以而且确实会随时更改。

您可以尝试 UID 会话 cookie 并仅将会话 ID 保存在浏览器 cookie 中,同时在用户数据库记录中保持连接状态。

为了集成设备依赖,经常使用请求头中的浏览器字符串,并保存在用户记录中。

这也是一种在系统更改(即TOS)后强制所有人登录的简便方法。

可能是练习连接状态图的好机会。

抱歉,我可能包含的任何代码都是特定于语言和集成的,但我也在我的用户 ID 中使用校验位,因此我可以在不使用数据库的情况下验证它们。 (另一个讨论的话题)