2017-04-20 76 views
-2

我一直在嘗試在php中創建自己的OOP風格的註冊登錄系統,我已經實現了一些安全功能,如使用htmlentites()的xss保護,爲SQL注入保護和基於令牌的準備方法表單提交csrf保護(目前我被阻止在我的代碼中實現此功能,提交表單數據時出現「無效標記」)。 但我不太確定安全網站是否足以生產真實的現場項目。我希望您查看我的代碼,請幫助我解決在我的代碼中實現令牌基礎表單提交,並向我建議改進我當前代碼中的編碼風格的方法。如何在PHP中實現令牌基表格提交

這是我的register.php頁面

<?php 
//error_reporting(0); 
session_start(); 


if(isset($_POST["submit"])){ 
    include "Db_handlers.php"; 
    $db = new DbHandler(); 
    $res = $db->createUser($_POST["name"], $_POST["email"], $_POST["password"], $_POST["re-password"], $_POST['token']); 
    print_r($res); 
    /*if($res){ 
     echo "test"; 
    } 
    else { 
     echo $res; 
    }*/ 
} 
$token = $_SESSION['token'] = md5(uniqid(mt_rand(),true)); 

?> 

<form action="<?=$_SERVER['PHP_SELF'];?>" method="post"> 
    <div class="field"> 
     <label for="name">Name:</label> 
     <input type="text" name="name" value="" />  
    </div> 
    <div class="field"> 
     <label for="email">Email:</label> 
     <input type="text" name="email" value="" />  
    </div> 
    <div class="field"> 
     <label for="password">Password:</label> 
     <input type="password" name="password" value="" />  
    </div> 
    <div class="field"> 
     <label for="repassword">Re-Password:</label> 
     <input type="password" name="re-password" value="" />  
    </div> 
    <input type="hidden" name="token" value="<?=$token;?>"/> 
    <input type="submit" name="submit" value="submit" /> 
</form> 

這是我的數據庫處理類

<?php 
    require 'functions.php'; 

    class DbHandler { 

    private $conn; 

    public function __construct() { 

    try{ 

    $this->conn = new PDO("mysql:host=127.0.0.1;dbname=task_manager", "root" , ""); 

    // echo "Connected"; 
    } 
    catch(PDOException $e){ 
     //die($e->getMessage()); 
     echo "Connection Failed: ".$e->getMessage(); 
    } 
    } 

    public function createUser($name, $email, $password, $repassword, $utoken) { 
    // $error = array(); 
    $error = ''; 
    $required_fields = array($name, $email, $password, $repassword); 
    $fields = array_map('trim', $required_fields); 
    if (in_array(null, $fields)) { 
     $error = 'Fields marked with an asterisk are required'; 
    } 

    else if($this->valid_token($utoken) == false){ 
     $error = "Invalid Token...!!!"; 
    } 

    else if(!filter_var($email, FILTER_VALIDATE_EMAIL)) { 
     $error = 'Please enter a valid email address !'; 
    } 

    else if(strlen($password) < 6){ 
     $error = "Password must be atleast 6 characters"; 
    } 

    else if($password !== $repassword){ 
     $error = "Password do n\' t match!!"; 
    } 
    else{ 
     $name = escape($name); 
     $email = escape($email); 
     $password_hash = escape($password); 
     // First check if user already existed in db 
     if (!$this->isUserExists($email)) { 
     // Generating password hash 
     $password_hash = password_hash($password, PASSWORD_DEFAULT, ['cost'=>12]); 
     // insert query 
     $stmt = $this->conn->prepare("INSERT INTO users(name, email, password_hash, status) values(:name, :email, :password_hash, 1)"); 
     //$stmt->bind_param("ssss", $name, $email, $password_hash); 
     $result = $stmt->execute(array(':name' => $name,':email' => $email,':password_hash' => $password_hash));; 
    //$stmt->close(); 
    // Check for successful insertion 
    if ($result) { 
    // User successfully inserted 
     return $result; 
     } else { 
     // Failed to create user 
     $error = "Failed to create user"; 
     } 
     } else { 
     // User with same email already existed in the db 
     $error = "User already exists"; 
     } 
     } 
     return $error; 
    } 




    private function isUserExists($email) { 
     $stmt = $this->conn->prepare("SELECT id from users WHERE email = :email"); 
     //$stmt->bind_param("s", $email); 
     $stmt->execute(array(':email' => $email)); 
     //$stmt->bind_result(); 
     $num_rows = $stmt->rowCount(); 
     //$stmt->close(); 
     return $num_rows > 0; 
    } 


    public function valid_token($token){ 
     if(!isset($_SESSION['token']) || $token != $_SESSION['token']) 
     return false; 
    } 
    } 
+2

有沒有聽說過代碼縮進?這太可怕了 – Option

回答

0

你的代碼是真的很難看......你應該正確縮進它。

回到你的問題。看起來,如果您的令牌不正確,您只需返回false,但如果正確,您忘記返回true。如果你沒有返回任何東西,你隱含返回null,其值爲false。我想,你的代碼工作,如果你的變化valid_token是這樣的:

public function valid_token($token){ 
    return isset($_SESSION['token']) && $token == $_SESSION['token']; 
} 
+0

現在它工作! (!$ this-> valid_token($ utoken)){ \t \t \t $ error =「無效的令牌... !!!」;當我在驗證部分中更改這個時,能夠提交表單。 \t \t}謝謝。 @Philipp可以編寫這樣的代碼來進行令牌基礎表單提交嗎?我的代碼是否適合這種安全功能?謝謝 – user3909370