Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 登录、用户身份验证、会话和csrf令牌_Php_Database_Session_Authentication - Fatal编程技术网

Php 登录、用户身份验证、会话和csrf令牌

Php 登录、用户身份验证、会话和csrf令牌,php,database,session,authentication,Php,Database,Session,Authentication,大约一个半月前,我开始学习PHP,我开始尝试创建自己的非常简单的CMS,以学习如何构建与mysql数据库交互的基本CRUD脚本等等 我目前正在为CMS的私有管理部分构建登录表单,通过这样做,我想了解PHP的基本安全性 我想做一些关于用户身份验证的基础研究,但我遇到的解释经常包括关于最佳安全实践的信息,我并不完全理解这些信息 因此,我寻找了更多关于我不了解的小部分的信息,其中包括我不熟悉的其他部分,我被卷入了大量关于安全主题的信息中,比如通过模糊性实现的安全性、单向密码散列、通过正确的php配置设

大约一个半月前,我开始学习PHP,我开始尝试创建自己的非常简单的CMS,以学习如何构建与mysql数据库交互的基本CRUD脚本等等

我目前正在为CMS的私有管理部分构建登录表单,通过这样做,我想了解PHP的基本安全性

我想做一些关于用户身份验证的基础研究,但我遇到的解释经常包括关于最佳安全实践的信息,我并不完全理解这些信息

因此,我寻找了更多关于我不了解的小部分的信息,其中包括我不熟悉的其他部分,我被卷入了大量关于安全主题的信息中,比如通过模糊性实现的安全性、单向密码散列、通过正确的php配置设置实现的安全性、防止sql注入、,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令牌有何帮助

如果攻击者劫持了用户的会话,则根据会话检查令牌没有帮助,因为攻击者拥有有效的会话

我错过了什么

我脑子里对事情的运作有一些知识空白,我希望你能帮我填补这些空白

  • 这是我希望将会话存储在中的唯一原因吗 数据库
  • 数据库受密码保护,会话目录不受密码保护。不用说,大多数服务器都应该保护/tmp/session路径(iirc),没有人可以访问它。。但同样,你必须非常信任主人。

  • 第二,在数据库中存储会话如何解决访问问题
  • 见答案#1

  • 换句话说,仅仅因为我将会话存储在数据库中,并不意味着服务器默认将其从存储会话的位置排除。这是正确的吗?如果是,我如何控制它
  • 基本上,会话由唯一标识符标识。浏览器被发送一个带有ID的cookie,服务器读取cookie ID并将其引用到服务器上的配置位置。要设置保存路径,可以使用-这将允许您对会话执行任何操作(保存时)-例如将会话保存到数据库。参见示例2。

  • 现在,如果用户已登录,如何进行身份验证
  • **有多种方法可以确定用户是否已登录。一种基本方法是在会话中存储唯一的数据,并将其与users表关联。当浏览器发送会话ID时,服务器可以根据ID检索数据。然后,您可以获取此数据并将其与用户表交叉引用以验证用户。记住,服务器(通常)是无状态的,这意味着在页面之间导航,服务器不会在页面之间跟踪用户。因此使用会话。一个非常基本的例子,我不想用这个,是这样的:

    <?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;
    }
    ?>
    
    
    
  • 但是,由于用户会话存储在数据库中,我是否可以直接使用它,还是需要先将其从数据库中拉出才能使用它
  • 不要将用户会话与用户对象本身混淆。会话用于将实际用户和应用程序绑定在一起。参见以上答案和示例

  • 在这种情况下,存储在表单上隐藏字段中的csrf令牌有何帮助
  • 当表单中有CSRF令牌时,服务器上也有CSRF令牌。。。这意味着当加载带有表单的页面时,CSRF令牌是gen