简体   繁体   English

如何优化我的登录脚本?

[英]How can I optimize my login script?

I've created an Ajax login for my website but I feel like I can optimize it, but I'm not sure how and where. 我为我的网站创建了一个Ajax登录,但我觉得我可以优化它,但我不确定如何以及在哪里。

Questions: 问题:

  • How can I optimize my code? 如何优化我的代码?
  • Is the code secure? 代码安全吗? Any ways to break it (injection, etc)? 有什么方法可以打破它(注射等)?

Also, when I attempt to log in, it currently takes about 1 second to process the login (on localhost). 此外,当我尝试登录时,目前需要大约1秒来处理登录(在localhost上)。 Is this long? 这很长吗?

Here's my Ajax call: 这是我的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);
        }
      }
    });
  });
});

Here's the PHP script: 这是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; 
  }

?>

How can I optimize my script to look better, be faster, etc? 如何优化我的脚本以使其更好看,更快,等等?

The problem with your one second delay is the connection to localhost , this is an issue with PDO. 您的一秒延迟的问题是与localhost的连接,这是PDO的问题。 Simply change localhost to 127.0.0.1 to solve the delay issue. 只需将localhost更改为127.0.0.1即可解决延迟问题。

The rest of the code looks nice and clean to me, good job. 其余的代码对我来说看起来很干净,干得好。 :) :)

Looks generally good. 看起来一般都不错 Couple of things at first glance: 乍一看几件事:

Your greater than 0 is redundant in your if statement: 在if语句中,大于0是多余的:

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

One would assume your username is unique. 可以假设您的用户名是唯一的。 As such, you shouldn't need to loop the results. 因此,您不需要循环结果。

Assuming your _id fields are autoincrement primary key fields, you don't need to specify them in the queries. 假设您的_id字段是自动增量主键字段,则无需在查询中指定它们。 Ie remove them from the fields and values list. 即从字段和值列表中删除它们。

Examine your use of the IP address. 检查您对IP地址的使用。 You're using it here to ensure login security but you're taking it from a range of user supplied headers. 您在此处使用它来确保登录安全性,但您可以从一系列用户提供的标头中获取它。 I'd suggest that, unless there's a good reason to get the 'real' IP, you should just use REMOTE_ADDR. 我建议,除非有充分的理由获得“真正的”IP,否则你应该使用REMOTE_ADDR。

Your "SELECT cookie, did I select something? UPDATE or INSERT" logic could be cut down by using an INSERT INTO ... ON DUPLICATE KEY UPDATE ... See the MySQL manual on INSERT for the syntax. 您的“SELECT cookie,我选择了什么吗?UPDATE或INSERT”逻辑可以通过使用INSERT INTO ... ON DUPLICATE KEY UPDATE来减少...请参阅INSERT上的MySQL手册以获取语法。

You're using cookies to store the username/hash. 您正在使用cookie来存储用户名/哈希。 Consider if you really need to do this as it adds complexity to your logic of having to check that the username in the cookie is what it's supposed to be each time it's required. 考虑一下你是否真的需要这样做,因为它增加了你必须检查cookie中的用户名是否应该是每次需要时的逻辑的复杂性。 If you can get away with using $_SESSION, I'd suggest doing so. 如果你可以使用$ _SESSION,我建议这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM