Php 令牌不匹配(CSRF)

Php 令牌不匹配(CSRF),php,csrf,Php,Csrf,我已经输入了以下代码,以防止CSRF,但发行和检查代币。 顶部是login.php,第二部分是登录页。令牌的发布是有效的,当我在登录页上打印$_SESSION['token']时,它们匹配起来。然而,当我替换中的其他代码时,它表示它们不匹配并显示“过期” <?php session_start(); $_SESSION['token'] = $token; $_SESSION['token'] = uniqid(md5(microtime()), true); print $_SESSI

我已经输入了以下代码,以防止CSRF,但发行和检查代币。 顶部是login.php,第二部分是登录页。令牌的发布是有效的,当我在登录页上打印$_SESSION['token']时,它们匹配起来。然而,当我替换中的其他代码时,它表示它们不匹配并显示“过期”

<?php
session_start();
$_SESSION['token'] = $token;
$_SESSION['token'] = uniqid(md5(microtime()), true); 
print $_SESSION['token'];
?>

<html>
<head>
    <title>My first PHP website</title>
</head>
<body>
    <h2>Please login here to see your tour</h2>
    <form action= "checklogin.php" method="post">
        Enter Username: <input type="text" name="username" required="required"/> <br/>
        Enter Password: <input type="password" name="password" required="required" /> <br/>
        <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" />
    <input type="submit" value= "login" />

    </form>
</body>

我的第一个PHP网站
请登录此处查看您的游览
输入用户名:
输入密码:

表单操作是login.php,因此当用户登录POST时,数据将提交到login.php页面。您的问题没有解释用户如何被引导到其登录页

一个选择是尝试以下方法

替换:

<form action="login.php" method="post">

根据我们对您问题的评论中的讨论,我将发布此答案,以便对信息进行总结

您的代码基本上是正确的,但您遇到的问题是,在重定向到用户的唯一登录页后,您无法再访问
$\u POST
中的数据,您最初在
checklogin.php
中拥有这些数据,即在提交登录表单之后

因此,在您的
checklogin.php
脚本中,您有以下选项:

  • 在重定向到的URL中包含令牌,然后对照
    $\u GET['token']
    检查会话['token']

  • $\u会话
    中设置一个标志,指示允许用户访问系统。类似于
    $\u SESSION['loggedIn']=true(这是我的建议)

  • 注意:这里您面临另一个问题:您必须考虑将每个用户的访问权限限制为只访问他们自己的页面。想象一下,如果一个用户不知何故知道另一个用户主页的URL,他们就可以轻松地编辑URL并访问它。我的建议是在
    $\u会话中保存用户id,然后在每个用户的主页顶部检查当前登录的用户是否允许打开所述页面


    我希望这能让事情变得更清楚

    您正在使用
    $\u GET['token']
    但是您的表单使用了
    POST
    方法,因此您应该使用
    $\u POST['token']
    来代替,即
    如果($\u POST['token'!=$\u SESSION['token'])
    @mrun谢谢您的建议,我试过了,但没有成功。因此我改变了我的帖子。为什么两个
    session_start()第二个(验证)文件中的行?@MarkBaker它们位于两个不同的php文件中,上面的一个在login.php上,下面的一个是我的目标文件。@Rus84我刚刚测试了你的代码,它对我有效。我在你的表单中没有看到提交按钮。你确定要提交吗?尝试在
    login.php
    中打印$\u POST['token']
    。是的,你是对的。当我在checklogin上使用重定向时,出现了一些困难。因此,一旦他们登录到checklogin.php,他们的用户名和密码将与数据库中存储的内容进行比较。然后根据用户ID将它们发送到自己的唯一页面。因此,我假设我需要检查该页面上的令牌以及最终的php文件是否匹配?如果我理解正确,您只需要确保令牌仅在logincheck.php上匹配。我想检查令牌是否首先在checklogin.php上匹配,然后匹配到其重定向位置file1.php。为什么要检查令牌再一次?我认为,只需检查表单提交上的令牌即可。看看这个,了解更多关于CSRF令牌如何工作的信息:是的,总结是正确的。注释部分完全正确,这是我对安全性的主要关注之一。我是php新手,在工作中通过反复试验学习(可以这么说)。用户名、密码、页面ID都保存在MYSQL数据库中。Id会话是否存储在checklogin.php中?然后在file1.php file2.php等的顶部,您将检查以确保正确的用户访问了该文件?谢谢,没错。您可以将用户id保存在checklogin.php中的
    $\u SESSION
    中,然后检查每个文件是否允许用户访问该文件。顺便说一句,有很多更好的方法可以做到这一点,但因为这是你选择的构建应用程序的方式,而不是其中一种方式。想象一下你需要写多少张支票。。。在每个文件中。然后,如果您决定添加另一个条件,用户是否可以访问该文件?正确的!你必须更改所有文件!所以你可能应该想一个方法来改进你的应用程序的这一部分:-)我想知道你是否可以帮我解决你上面推荐的第二点,设置一个标志。如何在最终的php文件中设置一些内容,以显示他们能够查看页面?非常感谢您提供的任何代码。谢谢。对不起,我离开了几天,我会尽量在今天晚些时候或明天建议一些帮助
    <form action="login.php" method="post">
    
    <form action="landingpage.php" method="post">
    
    $_POST['token']