form submit { email|password }
php filter/check { mysql_real_escape_string etc... }
php set/login.php {
$hash_logged = sha1(rand(100000,999999).$_SERVER["REMOTE_ADDR"].time());
$_SESSION["hl"] = $hash_logged;
mysql_query("UPDATE `users` SET `hash_logged`='".$hash_logged."' WHERE
`email`='".$emailLogin."'")or die(mysql_error());
setcookie("hlc", sha1($emailLogin."longstringtoguess"), time() + 600);
}
所有文件之上的 PHP 脚本.php以验证用户是否已登录:
if(isset($_SESSION["hl"], $_COOKIE["hlc"]))
{
$ext_hl =$_SESSION["hl"];
$ext_cookie = $_COOKIE["hlc"];
if(empty($ext_hl)) { header("location: logout.php"); exit(); }
if(empty($ext_cookie)) { header("location: logout.php"); exit(); }
$mysqlQ = mysql_query("SELECT `id`, `username`, `email`, `password` FROM `users`
WHERE `hash_logged`='".$ext_hl."'")or die(mysql_error());
if(mysql_num_rows($mysqlQ) == 1)
{
$row = mysql_fetch_array($mysqlQ);
if(sha1($row["email"]."longstringtoguess") == $ext_cookie)
{
$logged = "yes";
}
else {
header("location: logout.php");
exit();
}
}
else { header("location: logout.php"); exit(); }
}
注销.php
会话销毁/取消设置标头位置:索引.php
这种方法是否足够安全?你有什么方法可以做到这一点?
谢谢
这样做的一个问题是用户想要从两个设备(并且有两个不同的IP地址(或连接(cuch作为移动/拨号(连接的用户,其中IP地址可能会改变。理想情况下,您将有一个记录hash_id和user_id的"会话"表,然后用户连接到"会话",然后您知道从该表连接了哪个用户。
鼓励使用 PDO 进行数据库输入。 http://php.net/manual/en/book.pdo.php 起初很可怕,但很有意义,很快就会成为第二天性("容易"(。
如果需要,您还可以确保您的会话"过期"。
您的代码受制于可能窃取cookie并欺骗REMOTE_ADDR的人,或者如果有人知道电子邮件地址并且可以破解密钥 - 但在大多数情况下,这就足够了。您可以添加额外的投影,例如存储针对会话的user_agent(再次可欺骗(或向哈希添加更多投影(轮换密钥(等,以使其难以破解。
这种方法足够安全吗?你有什么方法可以做到这一点?
- 我不允许通过
set/login.php
中的$emailLogin
进行SQL注入。我更喜欢通过 EasyDB 使用预准备语句。 - 我不会将用户与会话关联(一对一(,而是将当前会话与用户帐户关联(多对一(。这允许用户独立于多个设备安全进行身份验证。
- 我只是使用
session_start()
而不是尝试构建一个看似安全的随机值。如果我需要直接创建随机性,我会使用random_bytes()
. - 我从不使用
==
来比较字符串。- 我改用
hash_equals()
。 - 违规线:
if(sha1($row["email"]."longstringtoguess") == $ext_cookie)
- 我改用