Php 登录、用户身份验证、会话和csrf令牌
大约一个半月前,我开始学习PHP,我开始尝试创建自己的非常简单的CMS,以学习如何构建与mysql数据库交互的基本CRUD脚本等等 我目前正在为CMS的私有管理部分构建登录表单,通过这样做,我想了解PHP的基本安全性 我想做一些关于用户身份验证的基础研究,但我遇到的解释经常包括关于最佳安全实践的信息,我并不完全理解这些信息 因此,我寻找了更多关于我不了解的小部分的信息,其中包括我不熟悉的其他部分,我被卷入了大量关于安全主题的信息中,比如通过模糊性实现的安全性、单向密码散列、通过正确的php配置设置实现的安全性、防止sql注入、,php注入、会话劫持等 我很难实现这一切,因为我无法真正理解这一切 因此,第一个问题是关于在数据库中存储用户会话 目前我所知道的是,如果我使用的是共享主机,服务器可能没有正确配置,服务器存储会话的文件夹可能会被其他人访问 这是我希望将会话存储在数据库中的唯一原因吗 第二,在数据库中存储会话如何解决访问问题 为了详细说明我的困惑,我很清楚,一旦会话存储在数据库中,共享主机上的人就可以安全地访问它,但是我如何告诉php-“嘿,我将用户会话存储在数据库中,在默认情况下,将其从指示存储它的位置排除” 换句话说,仅仅因为我将会话存储在数据库中,并不意味着服务器默认将其从存储会话的位置排除。这是正确的吗?如果是,我如何控制它 第三,如何在数据库中实际存储会话?我假设以下过程:Php 登录、用户身份验证、会话和csrf令牌,php,database,session,authentication,Php,Database,Session,Authentication,大约一个半月前,我开始学习PHP,我开始尝试创建自己的非常简单的CMS,以学习如何构建与mysql数据库交互的基本CRUD脚本等等 我目前正在为CMS的私有管理部分构建登录表单,通过这样做,我想了解PHP的基本安全性 我想做一些关于用户身份验证的基础研究,但我遇到的解释经常包括关于最佳安全实践的信息,我并不完全理解这些信息 因此,我寻找了更多关于我不了解的小部分的信息,其中包括我不熟悉的其他部分,我被卷入了大量关于安全主题的信息中,比如通过模糊性实现的安全性、单向密码散列、通过正确的php配置设
session_start();
//Assume a user has successfully logged in
//For better security regenerate the session on login
$session = session_regenerate_id();
$data[]= $session;
$query = $db_connection->prepare("INSERT INTO `sessions`(`session`) VALUES (?)");
$query->execute($data);
这就是以最基本的形式将会话存储在数据库中的意义吗
继续下一个问题
假设我已经解决了上面的问题。现在,如果用户已登录,如何进行身份验证
通常我会这样做:
if(!isset($_SESSION['user'])) {
redirect_to('login.php');
}
但是,由于用户会话存储在数据库中,我是否可以直接使用它,还是需要先将其从数据库中拉出才能使用它
我知道,一旦会话启动,浏览器中就有一个加密/哈希(不知道是哪一个)会话cookie,称为PHPSESSID
但由于我将会话存储在数据库中,这意味着我将手动控制PHP通常自动执行的操作,在我的头脑中,流程链是生成->存储->加密/哈希->设置会话cookie
这个假设正确吗
最后是跨站点伪造请求
我的理解是,当用户登录时,他不知何故被诱骗点击链接等,该链接将复制其浏览器的cookie,现在攻击者拥有会话cookie并可以模拟用户
在这种情况下,存储在表单上隐藏字段中的csrf令牌有何帮助
如果攻击者劫持了用户的会话,则根据会话检查令牌没有帮助,因为攻击者拥有有效的会话
我错过了什么
我脑子里对事情的运作有一些知识空白,我希望你能帮我填补这些空白
<?php
function isLoggedIn() {
if(!empty($_SESSION['user'])) {
$uuid = $_SESSION['user']['uuid']; // universal unique id
$username = $_SESSION['user']['username']; // username
$last = $_SESSION['user']['last']; // last use of session
if($last > time() - 600) { // active last 10 minutes?
$stmt = $db->prepare("SELECT username FROM users WHERE uuid = :uuid");
$stmt->bindValue(":uuid", $uuid, PDO::PARAM_STR);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if($username == $user['username']) { // user is logged in. uuid on session matches uuid in users table
$_SESSION['user']['last'] = time();
return true;
}
}
}
session_destroy(); // clear everything!
return false;
}
?>