我在同一页面上有多个使用函数generate_token()的表单。如果它是唯一具有generate_token()函数的表单,我只能得到一个表单。我希望能够在同一个网页上拥有多个表单,每个表单都有自己的generate_token()函数。但是,当同一网页上的多个表单都具有generate_token()函数时,我似乎无法使其工作。有人可以帮我解决这个问题。感谢。
PHP函数
function real_domain(){
if(!isset($_SERVER['HTTP_REFERER'])){
return false;
} else {
$referer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
$server_host = $_SERVER['HTTP_HOST'];
return ($referer_host == $server_host) ? true : false;
}
}
function request_is_post(){
return filter_input(INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING) === 'POST';
}
function token(){
return md5(uniqid(rand(), true));
}
function generate_token(){
$token = token();
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();
return $token;
}
function destroy_token(){
$_SESSION['token'] = null;
$_SESSION['token_time'] = null;
return true;
}
function valid_token(){
if(isset($_POST['token']) && !is_array($_POST['token'])){
if(isset($_POST['token'])){
$user_token = $_POST['token'];
if(isset($_SESSION['token'])){
$stored_token = $_SESSION['token'];
return $user_token === $stored_token;
} else {
return false;
}
} else {
return false;
}
} else {
foreach($_POST['token'] as $token){
if(isset($token)){
$user_token = $token;
if(isset($_SESSION['token'])){
$stored_token = $_SESSION['token'];
return $user_token === $stored_token;
} else {
return false;
}
} else {
return false;
}
}
}
}
function token_time(){
$expire_token = 60 * 60 * 24;
if(isset($_SESSION['token_time'])){
$stored_time = $_SESSION['token_time'];
return ($stored_time + $expire_token) >= time();
} else {
destroy_token();
return false;
}
}
表单验证
if(real_domain()){
if(request_is_post()){
if(valid_token()){
if(token_time()){
$errors = '';
$success = '';
if(isset($_POST['submit_comment'])){
$post_id = filter_numbers($_POST['post_id']);
$comment = filter_members_string($_POST['comment']);
if(!empty($_POST['comment'])){
if(empty($comment)){
$errors .= '<p class="error">✱ Error.</p>';
} else {
if(strlen(html_entity_decode($comment, ENT_NOQUOTES, 'UTF-8')) >= 5001){
$errors .= '<p class="error">✱ Error.</p>';
} else {
if($_POST['comment'] !== $comment){
$errors .= '<p class="error">✱ Error.</p>';
} else {
$success .= '<p class="success">✔ Your comment was posted.</p>';
}
}
}
}
if(!empty($success) && empty($errors)){
$query = "INSERT `post_comments` (`post_id`, `member_id`, `comment`, `date_created`)
VALUES('$post_id ', '" . $_SESSION['member_id'] . "', '$comment_value', NOW())";
mysqli_query(database(), $query);
}
if(empty($success) && empty($errors)){
$errors .= '<p class="error">✱ Your comment was not posted.</p>';
}
}
}
}
}
}
HTML表单
<form method="post" action="" class="post-form">
<fieldset>
<ol>
<li><label for="post-info-2" class="post-header">Post</label></li>
<li><textarea name="post" id="post-info-2"></textarea></li>
</ol>
</fieldset>
<fieldset>
<ol>
<li><input type="submit" name="submit_post" value="Submit Post" class="submit-post" /><input type="hidden" name="token" value="<?php echo generate_token(); ?>" /></li>
</ol>
</fieldset>
</form>
<form method="post" action="" class="post-form">
<fieldset>
<ol>
<li><label for="post-info" class="post-header">Post</label></li>
<li><textarea name="post" id="post-info"></textarea></li>
</ol>
</fieldset>
<fieldset>
<ol>
<li><input type="submit" name="submit_post" value="Submit Post" class="submit-post" /><input type="hidden" name="token" value="<?php echo generate_token(); ?>" /></li>
</ol>
</fieldset>
</form>
答案 0 :(得分:1)
在您的代码中,
function generate_token(){
$token = token();
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();
return $token;
}
每次调用该函数时, $_SESSION['token']
都会被覆盖。您需要将其更改为数组,甚至可能是关联数组。
function generate_token() {
$token = token();
$_SESSION['token'][] = array('value' => $token, 'time' => time());
return $token;
}
然后,当您检查它时,您可以使用array_shift()
将令牌数量保持在合理的水平,或者只需删除$_SESSION
中的令牌密钥
对于function valid_token()
,您可以使用PHP命令in_array()
来查找它。
如果您正在为CSRF保护做这件事,那么通常最好使用围绕该块的代码,尝试并且是真的。查看OWASP,了解有关如何进行CSRF保护的信息。