簡體   English   中英

如何優化我的登錄腳本?

[英]How can I optimize my login script?

我為我的網站創建了一個Ajax登錄,但我覺得我可以優化它,但我不確定如何以及在哪里。

問題:

  • 如何優化我的代碼?
  • 代碼安全嗎? 有什么方法可以打破它(注射等)?

此外,當我嘗試登錄時,目前需要大約1秒來處理登錄(在localhost上)。 這很長嗎?

這是我的Ajax調用:

$(document).ready(function() {
  $(document).on("submit", "form", function(event) {
    event.preventDefault();
    $.ajax({
      url: 'assets/php/login_script.php',
      type: 'POST',
      data: $(this).serialize(),
      success: function(data) {
        if (data == true) {
          window.location.href = "index.php";
        } else {
          $("input[name=password_field]").focus();
          $(".error").html(data);
        }
      }
    });
  });
});

這是PHP腳本:

<?php

  include_once("access.php");

  $cxn = mysqli_connect($host, $user, $pass, $db) or die ("Couldn't connect to the server. Please try again.");

  $username = $_POST["username"];
  $password = $_POST["password"];
  $date = date('Y-m-d h:i:s', time());
  $ip_address = get_ip_address();
  $expire = time() + 86400 * 365;

  $options = array('cost' => 12);
  $hash_password = password_hash($password, PASSWORD_BCRYPT, $options);

  /* Log the login request. */
  $stmt = $cxn->prepare("INSERT INTO login_logs (log_id, username, password, datetime, ip_address) VALUES ('', ?, ?, ?, ?)");
  $stmt->bind_param('ssss', $username, $hash_password, $date, $ip_address);
  $stmt->execute();

  /* Get user information from database. */
  $stmt = $cxn->prepare('SELECT * FROM users WHERE username = ?');
  $stmt->bind_param('s', $username);
  $stmt->execute();
  $result = $stmt->get_result();

  /* If a result exists, continue. */
  if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
      $db_username = $row['username'];
      $db_password = $row['password'];
      $random_hash = password_hash(time() . $db_username . time(), PASSWORD_BCRYPT, $options); 

      /* Password matches. */
      if (password_verify($password, $db_password)) {

        /* Get user's cookie information in database. */
        $stmt2 = $cxn->prepare("SELECT * FROM cookies WHERE username = ?");
        $stmt2->bind_param('s', $db_username);
        $stmt2->execute();
        $result2 = $stmt2->get_result();

        /* If a result exists, update the cookie. */
        if ($result2->num_rows > 0) {
          $stmt = $cxn->prepare("UPDATE cookies SET hash = ? WHERE username = ?");
          $stmt->bind_param('ss', $random_hash, $db_username);
          $stmt->execute();

          setcookie("user", $db_username, $expire, "/");
          setcookie("hash", $random_hash, $expire, "/");
        } else {
          $stmt = $cxn->prepare("INSERT INTO cookies (cookie_id, username, hash) VALUES ('', ?, ?)");
          $stmt->bind_param('ss', $db_username, $random_hash);
          $stmt->execute();

          setcookie("user", $db_username, $expire, "/");
          setcookie("hash", $random_hash, $expire, "/");
        }

        echo true;
      } else {
        echo "Incorrect credentials.";
      }
    }
  } else {
    echo "Incorrect credentials.";
  }

  function get_ip_address() {
    $ip_address = '';
    if (getenv('HTTP_CLIENT_IP'))
      $ip_address = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
      $ip_address = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
      $ip_address = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
      $ip_address = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
      $ip_address = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
      $ip_address = getenv('REMOTE_ADDR');
    else
      $ip_address = 'UNKNOWN';

    return $ip_address; 
  }

?>

如何優化我的腳本以使其更好看,更快,等等?

您的一秒延遲的問題是與localhost的連接,這是PDO的問題。 只需將localhost更改為127.0.0.1即可解決延遲問題。

其余的代碼對我來說看起來很干凈,干得好。 :)

看起來一般都不錯 乍一看幾件事:

在if語句中,大於0是多余的:

if ($result->num_rows) {
if ($result2->num_rows) {

可以假設您的用戶名是唯一的。 因此,您不需要循環結果。

假設您的_id字段是自動增量主鍵字段,則無需在查詢中指定它們。 即從字段和值列表中刪除它們。

檢查您對IP地址的使用。 您在此處使用它來確保登錄安全性,但您可以從一系列用戶提供的標頭中獲取它。 我建議,除非有充分的理由獲得“真正的”IP,否則你應該使用REMOTE_ADDR。

您的“SELECT cookie,我選擇了什么嗎?UPDATE或INSERT”邏輯可以通過使用INSERT INTO ... ON DUPLICATE KEY UPDATE來減少...請參閱INSERT上的MySQL手冊以獲取語法。

您正在使用cookie來存儲用戶名/哈希。 考慮一下你是否真的需要這樣做,因為它增加了你必須檢查cookie中的用戶名是否應該是每次需要時的邏輯的復雜性。 如果你可以使用$ _SESSION,我建議這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM