Система входа не может войти - PullRequest
1 голос
/ 28 июля 2011

Моя проблема в том, что когда я пытаюсь войти в систему, мой скрипт переходит прямо в остальную часть моего цикла.Я попытался вставить операторы printf для отладки и обнаружил хэширование моих паролей в паролях со значениями в базе данных.

<?php
//include_once './bin/configDb.php';
//MySQL connection variables
$dbhost = 'localhost';
$dbname = 'ideabank';
$dbuser = 'xxx';
$dbpass = 'xxx';
$table = 'members';
// Connect to server and select databse.
//include_once './bin/connectDb.php';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
mysql_select_db($dbname, $conn);
// username and password sent from form, cleanout, esacpe string against sqlinj.
$username = mysql_real_escape_string($_POST['username']);
$password = hash('sha512', $_POST['password']);
printf("$username \n");
printf("$password \n");
$sql = "SELECT * FROM $table WHERE username = '$username' AND password = '$password'
";
$result=mysql_query($sql);
//$result = mysql_query("SELECT * FROM $table WHERE username = '$username' AND password = '$password'
//");
// Replace counting function based on database you are using.
$count=mysql_num_rows($result);
// If result matched $username and $password, table row must be 1 row
if($count==1){
// Register $username, $password and redirect to file "login_success.php"
session_register("username");
session_register("password");
header("location:login_success.php");
}
else {
echo "Wrong Username or Password";
}
exit ()
?>

моя база данных MYSQL выглядит так:

CREATE TABLE IF NOT EXISTS `members` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`password` varchar(256) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

Затем я добавил это, чтобы получить больше сообщений об ошибках

var_dump($count);

И также экспериментировал с моей строкой запроса

$sql = "SELECT * FROM $table WHERE username = '$username'";

, которая дала мне это значение

$ sqlint(0)

Таким образом, мой запрос ничего не возвращает.

Поэтому я изменил запрос sql, удалив переменную $ table с точным именем таблицы "members"

Иэто дало мне новую ошибку:

$sql Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in      
/var/www/ideabank/checklogin.php on line 35 Call Stack: 0.0002 657184 1. {main}() /var/www/ideabank/checklogin.php:0 0.0006 660584 2. mysql_num_rows() /var/www/ideabank   /checklogin.php:35 NULL

и строка 35 - это мой if ($ count == 1)

. Итак, я проверил простой запрос к базе данных

    SELECT * From members

В результате были показаны строки 0 - 5 (всего 6, запрос занял 0,0004 секунды)

Хорошо, поэтому я изменил запрос снова

$sql = "SELECT * FROM members WHERE password = '$password'";

результат:

$ sqlint (2)

Это правильно, так как у меня две учетные записи с одним и тем же паролем.

Итак, я сделал еще один запрос

$sql = "SELECT * FROM members WHERE username = '$username'";

Что имело бы смысл, поскольку имя пользователя УНИКАЛЬНО

result:

$ sql Предупреждение: mysql_num_rows () ожидаетпараметр 1 будет ресурсом, логическое значение указано в /var/www/ideabank/checklogin.php в строке 35 Стек вызовов: 0.0002 653256 1. {main} () /var/www/ideabank/checklogin.php:0 0.0007 656528 2.mysql_num_rows () /var/www/ideabank/checklogin.php:35 NULL

Поскольку предупреждение указывает на наличие ошибки в строке 35, верните NULL!

Строка, которая создает предупреждение,мой счетчик, который служит для того, чтобы обеспечить отображение только одной записи.

Моя первоначальная идея была

, если результат соответствует $ username & $ password, тогда строка должна быть от == до 1

Но он выдает ту же ошибку SQL

Теперь я попытался изменить счетчик и использовать вместо него mysql_num_rows

if (
mysql_num_rows($result))
{
session_start();
...
eller
if (
mysql_num_rows($result) == 1)
{
session_start();
...

Но он все равно выдает предупреждение SQL.

Ответы [ 4 ]

1 голос
/ 28 июля 2011

Попробуйте: $result=mysql_query($sql,$conn); (При выполнении запроса необходимо указать, какое соединение использовать).

Когда mysql_query оператора SELECT успешен, он возвращает ресурс, в случае неудачи возвращает false (логическое значение - именно то, на что mysql_num_rows жалуется),Вы должны убедиться, что часть mysql_query выполнена успешно, прежде чем запрашивать информацию о строках.

В частности, давайте добавим некоторый код для отлова ошибок (только для целей разработки, а не для производства - никто не хочет видеть оператор dieпри использовании сайта - для производства должно отображаться приятное и, вероятно, гораздо менее описательное сообщение):

if (!$conn = mysql_connect($dbhost, $dbuser, $dbpass)) {
   //This is a horrible idea in production but shows you the failure 
   // while you're coding
   die ("Failed to connect to DB.");
}
if (!mysql_select_db($dbname, $conn)) {
   //Still a bad idea!
   die ("Unable to select DB $dbname");
}

/* ... */

if (!$result=mysql_query($sql,$conn)) {
   //Still bad!
   die ("Unable to execute $sql");
}

POST-переменные:

Вы должны проверить POST переменные!Возможно, вы не получили бы переменную username password ... вторая не будет сразу заметна, потому что алгоритм хеширования превратит пустую строку во что-то еще.

print_r($_POST); //Make sure you see username/password here

Или лучшевсе же:

if ($_POST['username']=="") {
  //Report username is required
} elseif ($_POST["password"]=="") {
  //Report password is required
}

Вы также можете рассмотреть суперглобальный $_REQUEST, который также допускает переменные $ _GET (test.php? username = me & password = 1234) и иногда $ _COOKIE {зависит от php.ini настроек}

Изменение стиля

Вы говорите:

Это правильно, поскольку у меня есть две учетные записи с одним и тем же паролем.

Возможно, вы захотите рассмотреть возможность уникальной посылки процесса хэширования, чтобы любые два пользователя с одинаковым паролем не имели одинакового хэшированного значения в БД .Самый простой способ сделать это - использовать имя пользователя (уже удобное уникальное значение), которое вы могли бы сначала хешировать (хотя вопрос о том, дает ли это преимущество, спорен).В существующем случае для вашей базы данных может быть использована атака rainbow table .

Вторым стилем является проверка имени пользователя / пароля.Я бы использовал SQL, чтобы получить запись пользователя (или ни одного, если они не пользователь), а затем использовать PHP для сравнения паролей, поэтому сценарий будет:

$username=mysql_real_escape_string($_POST['username']);

//First lookup the user
$sql="SELECT username,password FROM members WHERE username='$username'";
if (!$result=mysql_query($sql,$conn)) {
  echo "Username or password is invalid.";
  exit();
  //In truth username not found - for testing you could be 
  // more specific, or perhaps log the event internally:
}

$user=mysql_fetch_assoc($result);
//Assumes only one user can ever match, well more accurately will only
// access the first user ever found.  (Reasonable since your user-create
// process would filter duplicate usernames, or perhaps a members.UNIQUEKEY

//Following will only work if you change the way passwords are stored

define("SITESALT","NaCL"); //Should likely be defined in a header library 
// (since other pages like account-creation will require it)
if ($user["password"]!=
    hash('sha512',$user["username"].SITESALT.$_POST["password"])) {
  echo "Username or password is invalid.";
  exit();
  //In truth password is incorrect - might want to log.
}

/* //Alternate based on your existing pwd storage
  if ($user["password"]!=hash('sha512',$_POST["password"])) {
    echo "Username or password is invalid.";
    exit();
  }*/

header("location:login_succes.php");

Удобное преимуществовыше, если вы добавляете другие пользовательские свойства, которые должны быть проверены при входе в систему (например, enabled = 1, expires> = now () и т. д.), которые должны предоставлять пользователю более конкретные сообщения (например, «срок действия вашей учетной записи истек»)работа уже заложена.

1 голос
/ 28 июля 2011

Начните с проверки возвращаемых значений mysql_query()

if( mysql_query($query) ) {
     // retrieve result
}
else {
    die( mysql_error() );
}

Узнайте об уязвимостях SQL-инъекций и о том, как их предотвратить в PHP.Ваш код - это кошмар безопасности, ожидающий своего появления.Начните с запуска имени пользователя и пароля через mysql_real_escape_string().Или, что еще лучше, используйте PDO , который дает вам заполнители.

Не используйте session_register()

0 голосов
/ 28 июля 2011

Поскольку вы используете sha512, вам следует изменить тип поля password на varchar(512), в противном случае ваши пароли будут обрезаны до 256 символов при записи в базу данных.

0 голосов
/ 28 июля 2011

а) session_register () устарела и ее следует избегать любой ценой.Вместо этого используйте $_SESSION['varname'] = $varvalue.Также убедитесь, что вы действительно выполнили session_start()

b) Ошибки базы данных, которые вы получаете, указывают на наличие ошибок в строках запроса.У вас нет обработки ошибок в вашем коде, поэтому измените все вызовы запросов к базе данных на:

$result = mysql_query($sql) or die($sql . "<br>" . mysql_error());

, это прервет ваш скрипт в том месте, где происходит ошибка, покажет вам строку запроса и чтоточная ошибка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...