标签 token 下的文章

PHP表单增加token验证,防止站外提交/重复提交/双击提交


原理在于生成一个随机字符串放在session里。提交表单后来验证这个字符串。可以做到防止他人自己写form来欺骗提交,重复提交或者双击提交。






Token.php

<?php

/*
 * Created on 2013-3-25
 *
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
function getToken($len = 32, $md5 = true) {
    # Seed random number generator
    # Only needed for PHP versions prior to 4.2
    mt_srand((double) microtime() * 1000000);
    # Array of characters, adjust as desired
    $chars = array (
        'Q',
        '@',
        '8',
        'y',
        '%',
        '^',
        '5',
        'Z',
        '(',
        'G',
        '_',
        'O',
        '`',
        'S',
        '-',
        'N',
        '<',
        'D',
        '{',
        '}',
        '[',
        ']',
        'h',
        ';',
        'W',
        '.',
        '/',
        '|',
        ':',
        '1',
        'E',
        'L',
        '4',
        '&',
        '6',
        '7',
        '#',
        '9',
        'a',
        'A',
        'b',
        'B',
        '~',
        'C',
        'd',
        '>',
        'e',
        '2',
        'f',
        'P',
        'g',
        ')',
        '?',
        'H',
        'i',
        'X',
        'U',
        'J',
        'k',
        'r',
        'l',
        '3',
        't',
        'M',
        'n',
        '=',
        'o',
        '+',
        'p',
        'F',
        'q',
        '!',
        'K',
        'R',
        's',
        'c',
        'm',
        'T',
        'v',
        'j',
        'u',
        'V',
        'w',
        ',',
        'x',
        'I',
        '$',
        'Y',
        'z',
        '*'
    );
    # Array indice friendly number of chars;
    $numChars = count($chars) - 1;
    $token = '';
    # Create random token at the specified length
    for ($i = 0; $i < $len; $i++)
        $token .= $chars[mt_rand(0, $numChars)];
    # Should token be run through md5?
    if ($md5) {
        # Number of 32 char chunks
        $chunks = ceil(strlen($token) / 32);
        $md5token = '';
        # Run each chunk through md5
        for ($i = 1; $i <= $chunks; $i++)
            $md5token .= md5(substr($token, $i * 32 - 32, 32));
        # Trim the token
        $token = substr($md5token, 0, $len);
    }
    return $token;
}
?>

form.php

<?php
include_once("token.php");
$token = getToken();
session_start();
$_SESSION['token'] = $token;
?>
<form action="action.php" method="post"
<input type="hidden" name="token" value="<?=$token?>" />
<!-- 其他input submit之类的 -->
</form>

action.php

<?php
session_start();
if($_POST['token'] == $_SESSION['token']){
    unset($_SESSION['token']);
    echo "这是一个正常的提交请求";
}else{
    echo "这是一个非法的提交请求";
}
?>