2013-01-16 131 views
1

我试图用准备好的语句来制作PHP脚本以避免SQL注入。另外我创建了3个php文件。通过PHP验证用户

  1. db_connect.php(这里存储所有信息,用于连接到数据库)

  2. functions.php(创建会议,检查登录尝试,和功能login -where我可能犯了一个错误,但不能找到它)

  3. process_login.php(一组两个文件的上方,还重定向到login_success,错误页面,或者打印无效的请求如果没有POST变量发送到此页面)。

在增补为functions.php这里可能是错误的,因为我得到每次我试图插入一些值时间无效的请求。不管这些字段是空的还是包含数据库用户的值。

<?php 


function sec_session_start() { 
    $session_name = 'sec_session_id'; // Set a custom session name 
    $secure = false; // Set to true if using https. 
    $httponly = true; // This stops javascript being able to access the session id. 

    ini_set('session.use_only_cookies', 1); // Forces sessions to only use cookies. 
    $cookieParams = session_get_cookie_params(); // Gets current cookies params. 
    session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); 
    session_name($session_name); // Sets the session name to the one set above. 
    session_start(); // Start the php session 
    session_regenerate_id(true); // regenerated the session, delete the old one. 
} 

function login($postcode, $ref, $mysqli) { 
    // Using prepared Statements means that SQL injection is not possible. 
if ($stmt = $mysqli->prepare("SELECT ref_no, postcode FROM customers WHERE ref_no = ?   LIMIT 1")) { 
    $stmt->bind_param('ss', $postcode,$ref); // Bind "$email" to parameter. 
    $stmt->execute(); // Execute the prepared query. 
    $stmt->bind_result($dbref,$dbpostcode); // get variables from result. 
    // $stmt->fetch(); 
    $a = array(); 
while ($stmt->fetch()) { 
$a = array('ref' => $dbref , 'postcode' => $dbpostcode); 
} 

    if ($_POST['ref']==$dbref && $_POST['postcode']==$dbpostcode){ // If the user exists 
    // We check if the account is locked from too many login attempts 
    if(checkbrute($ref, $mysqli) == true) { 
     // Account is locked 

     return false; 
    } else { 
    if($dbref == $ref) { // Check if the password in the database matches the password the user submitted. 
     // Password is correct! 

      $ip_address = $_SERVER['REMOTE_ADDR']; // Get the IP address of the user. 
      $user_browser = $_SERVER['HTTP_USER_AGENT']; // Get the user-agent string of the user. 

      if(preg_match("/^[0-9a-zA-Z]{5,7}$/", $_POST["postcode"]) === 0) 
'<p class="errText">Please enter valid postcode!</p>'; 
      else{ $_SESSION['postcode'] = $postcode;} 
      if(preg_match("/^[0-9]{4,6}$/", $_POST["ref"]) === 0) '<p  class="errText">Please enter valid reference number ! </p>'; 
      else{ 
      $_SESSION['ref'] = $ref;} 
         // Login successful. 
      return true; 
    } else { 
     // Password is not correct 
     // We record this attempt in the database 
     $now = time(); 
     $mysqli->query("INSERT INTO login_attempts (ref_no, time) VALUES ('$ref', '$now')"); 
     return false; 
    } 
    } 
    } else { 
    // No user exists. 
    return false; 
    } 
    } 
    } 

function checkbrute($ref, $mysqli) { 
    // Get timestamp of current time 
    $now = time(); 
    // All login attempts are counted from the past 2 hours. 
    $valid_attempts = $now - (2 * 60 * 60); 

    if ($stmt = $mysqli->prepare("SELECT time FROM login_attempts WHERE ref_no = ? AND time > '$valid_attempts'")) { 
    $stmt->bind_param('i', $ref); 
    // Execute the prepared query. 
    $stmt->execute(); 
    $stmt->store_result(); 
    // If there has been more than 3 failed logins 
    if($stmt->num_rows > 3) { 
    return true; 
    } else { 
    return false; 
    } 
    } 
} 

?> 

而这是process_login.php用户验证失败。

<?php 
include 'db_connect.php'; 
include 'functions.php'; 


sec_session_start(); // 

if(isset($_POST['postcode'], $_POST['ref'])) { 

    if(login($postcode, $ref, $mysqli) == true) { 
    // Login success 
    echo 'Success: You have been logged in!'; 
} else { 
    // Login failed 
    header('Location: ./login.php?error=1'); 
    } 
} else { 
    // The correct POST variables were not sent to this page. 
    echo 'Invalid Request'; 
} 

?> 

任何帮助将是最受欢迎的。谢谢。

+0

在'process_login.php'的var_dump()你的$ _ POST右下方'sec_session_start();',看看如果有什么实际上是张贴。 'var_dump($ _ POST);' – kylex

+0

表单输入名称属性的命名是否正确? –

+0

谢谢你们的快速解答。我已经尝试var_dump($ _ POST),就像kylex说的,我得到:** array(0){}无效的请求** – user1981437

回答

1

您只有一个$变量进行绑定。您正试图绑定两个:

if ($stmt = $mysqli->prepare("SELECT ref_no, postcode FROM customers WHERE ref_no = ?   LIMIT 1")) { 
    $stmt->bind_param('ss', $postcode,$ref); // Bind "$email" to parameter. 

只有一个?和两个bind_param ......

应该是:

if ($stmt = $mysqli->prepare("SELECT ref_no, postcode FROM customers WHERE ref_no = ?   LIMIT 1")) { 
    $stmt->bind_param('s', $ref); // Bind "$email" to parameter. 

我没有测试过这一点,但这里是我认为你需要登录功能:

function login($postcode, $ref, $mysqli) 
{ 
// Using prepared Statements means that SQL injection is not possible. 
if ($stmt = $mysqli->prepare("SELECT ref_no, postcode FROM customers WHERE ref_no = ? LIMIT 1")) 
    { 
     $stmt->bind_param('s',$ref); // Bind "$email" to parameter. 
     $stmt->execute(); // Execute the prepared query. 
     $stmt->store_result(); 
     $stmt->bind_result($dbref,$dbpostcode); // get variables from result. 
    while ($stmt->fetch()) 
     { 
     if($stmt->num_rows > 0) 
      { 
      $now = time(); 
      if ($_POST['ref'] == $dbref && $_POST['postcode'] == $dbpostcode) 
       {// If the user exists 
        if(checkbrute($ref, $mysqli) == true) 
         {        
          $mysqli->query("INSERT INTO login_attempts (ref_no, time) VALUES ('".$dbref."', '".$now."')"); 
          return false; 
         } 
        $ip_address = $_SERVER['REMOTE_ADDR']; // Get the IP address of the user. 
        $user_browser = $_SERVER['HTTP_USER_AGENT']; // Get the user-agent string of the user. 
        if(!preg_match("/^[0-9a-zA-Z]{5,7}$/", $_POST["postcode"])) 
         { 
          $mysqli->query("INSERT INTO login_attempts (ref_no, time) VALUES ('".$dbref."', '".$now."')"); 
          $error = '<p class="errText">Please enter valid postcode!</p>'; 
          return $error; 
         } 
        $_SESSION['postcode'] = $postcode; 
        if(!preg_match("/^[0-9]{4,6}$/", $_POST["ref"])) 
         { 
          $mysqli->query("INSERT INTO login_attempts (ref_no, time) VALUES ('".$dbref."', '".$now."')"); 
          $error = '<p class="errText">Please enter valid reference number ! </p>'; 
          return $error; 
         } 
        $_SESSION['ref'] = $ref; 
      return true; 
      } 
     //no rows returned 
     $mysqli->query("INSERT INTO login_attempts (ref_no, time) VALUES ('".$dbref."', '".$now."')"); 
     return false;  
     } 
    //no statement fetched 
    return false; 
    } 
//no statment prepared 
return false; 
} 

我加这回到代码中,但我不明白它的用法。它没有返回或使用在此范围内:

$ip_address = $_SERVER['REMOTE_ADDR']; // Get the IP address of the user. 
$user_browser = $_SERVER['HTTP_USER_AGENT']; // Get the user-agent string of the user. 
+0

感谢您的回答罗伊,我已经尝试过,但仍然是:/ – user1981437

+0

@ user1981437 I编辑我的答案以显示您的登录功能的返工。任何时候你使用'return',正确地完成你可以忽略'else'。我没有测试过,所以试试看。 –

1

尝试:

if ($stmt = $mysqli->prepare("SELECT ref_no, postcode FROM customers WHERE ref_no = ?   LIMIT 1")) { 
    $stmt->bind_param('%s%s', $postcode,$ref); // Bind "$email" to parameter. 
+2

谢谢Mostafa,我改变了我的代码,但仍然得到同样的错误。 – user1981437

+1

+1谢谢。祝你好运。 – shgnInc