0

我会让这个尽可能简短和甜蜜。

我有一个名为 usernameget.php 的脚本,它与当前登录的用户名相呼应:

<?php 
include 'functions.php';
include 'db_connect.php';
sec_session_start();

$userId = $_SESSION['user_id'];

if(login_check($mysqli) == true) {

$con=mysqli_connect("localhost","myusername","mypass","mysqldb");
// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }


$result = mysqli_query($con,"SELECT members.username FROM members WHERE id= $userId");

while ($row = mysqli_fetch_assoc($result)) 
{
   echo $row['username'];
}

/* free result set */
mysqli_free_result($result);

mysqli_close($con);

} else {
   echo 'Null User <br/>';
}

?>

该脚本使用functions.php(位于此处的安全登录脚本的一部分:http: //www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL#Create_PHP_Functions)来运行. sec_session_start(); 只是一个自定义 session_start,但 functions.php 也可以通过 $user_id 获取用户名。

问题是,当我在主页中包含 usernameget.php (也使用 functions.php 来保护)时,它会抛出错误,因为它试图重新声明 sec_session_start();

我可以剥夺 usernameget.php 的这种安全性,但显然因为它依赖于 functions.php / sec_session_start(); 之后它不起作用。我试图编写一个特定的 USERNAMEGETfunctions.php,但没有使用 usernameget.php 的会话内容,但我不够熟练,无法让它工作,感觉就像一个不优雅的解决方案。

据我了解:functions.php 和 sec_session_start(); 用于保护主页,因此主页上的包含不能使用functions.php,否则会发生冲突。谁能告诉我如何在不重新声明/冲突的情况下让这个脚本运行?

下面包含的是整个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(); // regenerated the session, delete the old one.  
}




function login($email, $password, $mysqli) {
   // Using prepared Statements means that SQL injection is not possible. 
   if ($stmt = $mysqli->prepare("SELECT id, username, password, salt FROM members WHERE email = ? LIMIT 1")) { 
      $stmt->bind_param('s', $email); // Bind "$email" to parameter.
      $stmt->execute(); // Execute the prepared query.
      $stmt->store_result();
      $stmt->bind_result($user_id, $username, $db_password, $salt); // get variables from result.
      $stmt->fetch();
      $password = hash('sha512', $password.$salt); // hash the password with the unique salt.

      if($stmt->num_rows == 1) { // If the user exists
         // We check if the account is locked from too many login attempts
         if(checkbrute($user_id, $mysqli) == true) { 
            // Account is locked
            // Send an email to user saying their account is locked
            return false;
         } else {
         if($db_password == $password) { // Check if the password in the database matches the password the user submitted. 
            // Password is correct!


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

               $user_id = preg_replace("/[^0-9]+/", "", $user_id); // XSS protection as we might print this value
               $_SESSION['user_id'] = $user_id; 
               $username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username); // XSS protection as we might print this value
               $_SESSION['username'] = $username;
               $_SESSION['login_string'] = hash('sha512', $password.$user_browser);
               // Login successful.
               return true;    
         } else {
            // Password is not correct
            // We record this attempt in the database
            $now = time();
            $mysqli->query("INSERT INTO login_attempts (user_id, time) VALUES ('$user_id', '$now')");
            return false;
         }
      }
      } else {
         // No user exists. 
         return false;
      }
   }
}




function checkbrute($user_id, $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 user_id = ? AND time > '$valid_attempts'")) { 
      $stmt->bind_param('i', $user_id); 
      // Execute the prepared query.
      $stmt->execute();
      $stmt->store_result();
      // If there has been more than 5 failed logins
      if($stmt->num_rows > 5) {
         return true;
      } else {
         return false;
      }
   }
}




function login_check($mysqli) {
   // Check if all session variables are set
   if(isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
     $user_id = $_SESSION['user_id'];
     $login_string = $_SESSION['login_string'];
     $username = $_SESSION['username'];

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

     if ($stmt = $mysqli->prepare("SELECT password FROM members WHERE id = ? LIMIT 1")) { 
        $stmt->bind_param('i', $user_id); // Bind "$user_id" to parameter.
        $stmt->execute(); // Execute the prepared query.
        $stmt->store_result();

        if($stmt->num_rows == 1) { // If the user exists
           $stmt->bind_result($password); // get variables from result.
           $stmt->fetch();
           $login_check = hash('sha512', $password.$user_browser);
           if($login_check == $login_string) {
              // Logged In!!!!
              return true;
           } else {
              // Not logged in
              return false;
           }
        } else {
            // Not logged in
            return false;
        }
     } else {
        // Not logged in
        return false;
     }
   } else {
     // Not logged in
     return false;
   }
}

?>
4

2 回答 2

1

您必须使用 require_once 而不是 include_once 因为您的程序不会在没有该文件的情况下运行...

include_once 在尝试包含文件但失败时会产生警告。尝试包含时 require_once 会产生致命错误,但它会失败。

对于核心库,您应该使用 require_once。(http://www.php.net/manual/pt_BR/function.require.php

require is identical to include except upon failure it will also produce a fatal E_COMPILE_ERROR level error. In other words, it will halt the script whereas include only emits a warning (E_WARNING) which allows the script to continue.
于 2013-10-16T19:14:49.057 回答
1

不要将 plaininclude用于核心函数库,这种库往往会包含在所有脚本中。改为使用include_once,这样 PHP 将只包含一次文件,然后忽略任何进一步的包含尝试。这将防止您的函数重新声明错误。

于 2013-10-16T18:47:42.717 回答