Tur*_*Ali 15 php cookies session login remember-me
在登录系统上工作并尝试实现记住我的功能.
最近,我做了关于这个主题的研究,阅读了一堆文章,帖子,故事,小说,童话(称之为,因为其中一些甚至不包含1行代码,只是大量的单词),cookie漏洞如固定,劫持......等
并决定实现以下目标
但我真的很困惑我的主要问题:哪种方式是正确的,为了"记住我"的功能?使用cookies/session/database?
请在代码上解释你的想法.(没有代码,我无法理解)
目前,我的代码看起来像那样
在登录期间,我使用以下功能来设置cookie和会话
protected function validateUser($userid, $ckey=0, $rememmber=0) {
session_start();
session_regenerate_id(true); //this is a security measure
$_SESSION['user_id'] = $userid;
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
if (isset($remember) && $rememmber == 'on') {
setcookie("user_id", $_SESSION['user_id'], time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/");
setcookie("user_key", sha1($ckey), time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/");
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
然后在安全用户页面上,检查user_id使用user_id从db获取有关用户的所有重要数据
public function protect() {
session_start();
/* Secure against Session Hijacking by checking user agent */
if (isset($_SESSION['HTTP_USER_AGENT'])) {
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) {
$this->signout();
exit;
}
}
// before we allow sessions, we need to check authentication key - ckey and ctime stored in database
/* If session not set, check for cookies set by Remember me */
if (!isset($_SESSION['user_id'])) {
if (isset($_COOKIE['user_id']) && isset($_COOKIE['user_key'])) {
/* we double check cookie expiry time against stored in database */
$cookie_user_id = $_COOKIE['user_id'];
$stmt = $this->db->prepare("select `ckey`,`ctime` from `users` where `id` =?") or die($this->db->error);
$stmt->bind_param("i", $cookie_user_id) or die(htmlspecialchars($stmt->error));
$stmt->execute() or die(htmlspecialchars($stmt->error));
$stmt->bind_result($ckey, $ctime) or die($stmt->error);
$stmt->close() or die(htmlspecialchars($stmt->error));
// coookie expiry
if ((time() - $ctime) > 60 * 60 * 24 * COOKIE_TIME_OUT) {
$this->signout();
}
/* Security check with untrusted cookies - dont trust value stored in cookie.
/* We also do authentication check of the `ckey` stored in cookie matches that stored in database during login */
if (!empty($ckey) && is_numeric($_COOKIE['user_id']) && $_COOKIE['key'] == sha1($ckey)) {
session_regenerate_id(); //against session fixation attacks.
$_SESSION['user_id'] = $_COOKIE['user_id'];
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
} else {
$this->signout();
}
} else {
if ($page != 'main') {
header('Location:' . wsurl);
exit();
}
}
}
Run Code Online (Sandbox Code Playgroud)
设置登录尝试之间的时间延迟(以防止暴力攻击)并限制尝试次数
那么你是按帐户提供DOS的方法吗?
几乎在每个操作上重新生成会话ID
呃,不.这实际上可能会击败对象.当前id过期或用户通过身份验证时,您应始终生成新的ID - 否则请不要管它.
但我真的很困惑我的主要问题:哪种方式是正确的,为了"记住我"的功能?使用cookies/session/database?
由于您需要在客户端上保留令牌,这意味着cookie(除非您喜欢使用本地存储编写非常复杂的内容).由于您不希望通过cookie/make伪造公开数据,这意味着它应该是一个随机值.并且为了协调存储的随机值,这意味着存储数据服务器 - 可能在数据库中,因为必须可以基于用户ID或基于随机值来引用数据.
虽然你可以使用一个非过期(或非常长寿)的会话,但我会远离这个 - 数据会滚雪球 - 并且偶尔更新会话数据是个好主意.
您还需要满足用户希望您在2台不同计算机上记住她的场景.如果您只为每个帐户保留一个"记住我"令牌,那么您必须在两个客户端使用相同的值,或者在创建新令牌时删除旧令牌(即用户只能在一台计算机上记住).
请解释您对代码的想法.没有代码,我无法理解清楚
不,我付钱写代码; 如果您希望我为您编写代码,那么您需要付我钱.代码将比上面的描述占用更多的空间和时间.
但我真的对我的主要问题感到困惑:对于“记住我”功能,哪种方式是正确的?使用cookie/会话/数据库?
Http 是一种无状态的协议调用。身份验证令牌必须持续存在才能保持状态。正确的方法是使用session。现在如何跟踪会话?由你决定。但饼干也不错。
在会话中,您可以保存根据浏览器不同条件(用户代理、操作系统、屏幕分辨率等)创建的哈希值,以检查令牌是否来自同一环境。您保存的标准越多,劫持就越困难。顺便说一句,你每次都需要 JavaScript 来获取额外的信息。
| 归档时间: |
|
| 查看次数: |
13938 次 |
| 最近记录: |