【问题标题】:Session/Cookie Issue?会话/Cookie 问题?
【发布时间】:2014-11-05 04:54:24
【问题描述】:

我在使用表单标记时遇到了一些困难。我有一个全局文件,我需要在所有控制器的顶部。

/*
 *----------------------------------------------
 *  VERIFY FORM TOKENS
 *----------------------------------------------
 */    
if ($_POST) {
    // Define and Sanitize
    $formToken           = $sanitize->input($utilities->getVar('formToken', 'session'));
    $authenticityToken   = $sanitize->input($utilities->getVar('authenticityToken'));

    // Validate
    if ($authenticityToken !== $formToken) {   
        $errors[] = 'There was a token mismatch error submitting your form. Please try again.';     
    }
}  

// Generate Form Token
$formToken =  $forms->token();
$_SESSION['formToken'] = $formToken;

在声明它们匹配后立即回显变量时。但是当我检查数据库(我将会话保存到数据库)时,每次数据库刷新都会显示一个已保存的新表单令牌。我只调用$forms->token(); 类,这就是它的样子

class Forms {
    public __construct(){}
    function token() {
        $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $token      = '';

        for ($i = 0; $i < 60; $i++) {       $token .= $characters[ rand( 0, strlen( $characters ) - 1 ) ];       }

        $hash       = substr(str_shuffle($token), 0, 32);

        return $hash;
     }
}

我一直在研究这个问题一段时间,我对为什么会发生这种情况感到困惑。我也在我的 .htaccess 文件中使用 mod_rewrite。我读到重写会影响会话,但所有其他会话数据都可以(会话登录数据等),只是这些令牌让我很难过。

【问题讨论】:

  • 为什么你认为你只给$forms-&gt;token();打了一次电话?看看你的代码,然后解释一下。
  • @developerwjk 我忘了添加类名,但我在全局文件顶部实例化了类(包括使用自动加载器),我调用了该类并将 var $formToken 设置为令牌由函数返回。我不确定我是否做错了。我正在尝试从程序转换为 oop。
  • 大概每次发布表单时都会调用第一个代码块......但是每次都在之后调用$forms-&gt;token();。要么你经常调用这个东西,要么你的代码没有意义。
  • $_POST 中定义的表单令牌是从$_SESSION[formToken] 中提取的var,authentitytoken 是从发布的formToken 中获取的。它们都被定义并被要求发布以进行验证。如果它们不匹配,则会产生错误,表单将暂停,并在 post check 下方发出新的表单令牌。如果表单已发布且未发生错误,则表单已完成,然后重定向用户并发出新的表单令牌

标签: php .htaccess session mod-rewrite cookies


【解决方案1】:

我认为你需要在生成令牌的地方加上一个 else。正如你所拥有的,看起来你得到了令牌,然后每次都创建一个新的。

if ($_POST) 
{
    // Define and Sanitize
    $formToken           = $sanitize->input($utilities->getVar('formToken', 'session'));
    $authenticityToken   = $sanitize->input($utilities->getVar('authenticityToken'));

    // Validate
    if ($authenticityToken !== $formToken)
    {   
        $errors[] = 'There was a token mismatch error submitting your form. Please try again.';     
   //UPDATE: MAYBE PUT IT HERE TOO:
        $formToken =  $forms->token();
        $_SESSION['formToken'] = $formToken;
    }
}  
else
{
   //----putting in an else so this is not done again on POST--------
   // Generate Form Token
   $formToken =  $forms->token();
   $_SESSION['formToken'] = $formToken;
}

【讨论】:

  • 仍然有同样的问题,这也不会让表单受到 csrf 攻击,因为隐藏的表单令牌和会话在发生错误时是相同的,并且两者都可以编辑。这很奇怪,因为当我删除 htaccess 中的所有重写时,我不再有这个问题。
  • @ICJ,更新了答案。也许当出现不匹配时,您需要重新创建它(?),但并非总是如此。
猜你喜欢
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
相关资源
最近更新 更多