ajax响应后的nonce令牌和使用ajax jquery类型json的哈希问题


nonce token after ajax response and hash problems using ajax jquery type json

我在php上用自己的代码登录,现在我不太擅长jquery ajax等等,我使用ajax jquery类型json登录,我获取所有vals并将它们发布到服务器端php,后者检查所有细节,并通过相同的jquery ajax进行响应。

问题是,我在登录表单中添加了php中制作的nonce令牌,每次用户尝试登录后,nonce都会更改,问题是只有当我刷新登录页面时,nonce才会更改为好的nonce,否则它会保持相同的nonce标记,并将随帖子发送,而不是更新后的,因为ajax在登录后没有刷新页面。

因此,问题是如何在每次响应后触发ajax来刷新nonce令牌?nonce令牌是用php编写的。

关于散列随机数令牌的更多信息,它会在某个时候生成散列字符串:

asdaskjn34kj+sdf/sd=

现在ajax jquery自动从哈希字符串中删除"+",因此它在POST中发送了错误的令牌,这里是我的散列函数:

public static function RandomBytes($count, $printable=FALSE)
    {
        $bytes = '';
    // supress warnings when open_basedir restricts access to /dev/urand
        if(@is_readable('/dev/urandom') && ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE)
        {
            $bytes = fread($hRand, $count);
            fclose($hRand);
        }
    if((strlen($bytes) < $count) && function_exists('mcrypt_create_iv'))
    {
        // Use MCRYPT_RAND on Windows hosts with PHP < 5.3.7, otherwise use MCRYPT_DEV_URANDOM
        // (http://bugs.php.net/55169).
        if ((version_compare(PHP_VERSION, '5.3.7', '<') && strncasecmp(PHP_OS, 'WIN', 3) == 0))
          $bytes = mcrypt_create_iv($count, MCRYPT_RAND);
        else
          $bytes = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
    }
    if((strlen($bytes) < $count) && function_exists('openssl_random_pseudo_bytes'))  // OpenSSL slow on Win
    {
        $bytes = openssl_random_pseudo_bytes($count);
    }
    if ((strlen($bytes) < $count) && @class_exists('COM'))
    {
        // Officially deprecated in Windows 7
        // http://msdn.microsoft.com/en-us/library/aa388182%28v=vs.85%29.aspx
        try
        {
            $CAPI_Util = new COM('CAPICOM.Utilities.1');
            if(is_callable(array($CAPI_Util,'GetRandom')))
            {
                $bytes = $CAPI_Util->GetRandom(16,0);
                $bytes = base64_decode($bytes);
            }
        }
        catch (Exception $ex)
        {
        }
    }
        if (strlen($bytes) < $count)
        {
            // This fallback here based on phpass code
            $bytes = '';
            $random_state = microtime();
            if (function_exists('getmypid'))
                $random_state .= getmypid();
            for ($i = 0; $i < $count; $i += 16) {
                $random_state =
                    md5(microtime() . $random_state);
                $bytes .=
                    pack('H*', md5($random_state));
            }
            $bytes = substr($bytes, 0, $count);
        }
        if ($printable)
            return base64_encode($bytes);
        else
            return $bytes;
    }

有人知道如何更改这个函数以使hashesh中没有"+"的字符串吗?

要更改哈希函数,如果只有"+"是问题,您可以在创建字符串时进行检查,

next_char = Randomly-created-char;
if(next_char == '+'){
 //do nothing
} else{
 hash .= next_char;
}

以下是html和php文件的样子。

ajax调用显示在.html文件中。

第一次加载表单的.php

<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
 $(document).ready(function(){
    $("#check").click(function(){
        $("#keyvalue").text($("#key").val());
    });
    $("#submit").click(function(){
    var text = $("#text").val();
    var key = $("#key").val();
        $.ajax({
            url: 'trial.php',
            data: {text: text, key:key},
            type: 'POST',
            dataType: 'json',
            success: function(data) {
                if(data.status == "fail"){
                    $("#status").html(data.message);
                }else{
                    $("#status").html(data.message);
                    $("#key").val(data.key);
                    $("#keyvalue").text('');
                }
            }
        });
        return false;
    });
 });
</script>
</head>
<body>
    <form method="post" action="trial.php" onsubmit="return send_form();">
        <input type="text" name="text" id="text"/>
        <input type="hidden" id="key" name="key" value="<?php echo $key?>"/> //Look here.
        <button id="submit">Send data and get new key</button>
    </form>
    <br><br>
    <div id="status"></div>
    <br><br>
    <button id="check">What's current value of key?</button> --------> <span id="keyvalue"></span>
    <div id="response"></div>
</body>
</html>

.php

<?php
//You get the form contents here.
$key = isset($_POST['key']) ? $_POST['key'] : "error";
$text = isset($_POST['text']) ? $_POST['text'] : "empty";
//Check them if it matches with DB's entry, if doesn't you set $key = "error";
if($key=="error"){
    $status = "fail";
    $message = "There was some error processing your form.";
    exit;
} else{
    //You generate another random key.
    $random ='';
    for ($i = 0; $i < 10; $i++) {
        $random .= chr(mt_rand(33, 126));
    }
    //Now here in steps save it to your DB. So that when next form is submitted you can match it.
    //And send back response to html file, where ajax will refresh the key.
    $status = "success";
    $message = "
    Your form was processed succesfully<br>
    The text you sent was ".$text.", and the key you sent was ".$key.".
    The new key sent to you can be seen by pressing the button below, has value, ".$random."<br><br>
    ";
    }
    echo json_encode(array("status" => $status, "message" => $message, "key" => $random));
?>

希望这对你有帮助。

在第一次生成表单时,您必须在不使用任何ajax的情况下提供密钥和nonce,当使用以下密钥时,将调用ajax函数。

echo "<input type='hidden' id='key' name='key' value='".$key."'>";
echo "<input type='hidden' id='nonce' name='nonce' value='".$nonce."'>";

这真的很有用,因为我遇到了同样的问题-我曾考虑过登录时自动刷新页面,但这对用户来说真的很不方便-我还添加了一个块,以便在5次尝试失败后阻止ip和/或用户