Аутентификация MySQL против PHP? - PullRequest
0 голосов
/ 10 марта 2011

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

Какой процесс аутентификации лучше?

Опция 1

$sql = "SELECT * FROM users WHERE username = $user  AND password = $password";
if($result){// success }

Вариант 2

$sql = 'SELECT * FROM USER WHERE username = $user';
///query goes here and returns to $result 
if(count($result)==1 && $_POST['passwod'] == $result['password']){
    /// success
}

Я всегда использовал второй вариант, но хочу узнать мнение другого человека.

Код может быть немногогрязный и уязвимый для хакеров, но только для демонстрационных целей.

Ответы [ 8 ]

3 голосов
/ 10 марта 2011

Я согласен с другими авторами, но для второго способа есть два момента:

  • Пароль не появляется в журнале запросов (ивозможно, slow-query-low), который может быть включен на некоторых серверах.
  • Вы можете вывести два разных сообщения об ошибках, одно «Пользователь не найден», а другое «Пароль неверен», если хотите.
3 голосов
/ 10 марта 2011

Обе опции 1 и 2 подразумевают хранение паролей в виде простого текста, что опасно. Если ваша база данных будет украдена (произошло с Gawker Media, случилось с Reddit, случилось с моей компанией), хакер получит доступ не только к учетным записям на вашем сайте, но и к учетным записям многих пользователей, поскольку люди обычно используют единый пароль для всех своих учетных записей.

Вариант 3. Хэшируйте свои пароли с помощью криптографической хеш-функции (подсказка: не MD5) и соли random . См. этот вопрос для решения PHP, которое используется в WordPress и Drupal. Поскольку вы не можете проверить соленый пароль без предварительного извлечения соли из базы данных, это решение ближе к вашему второму варианту.

3 голосов
/ 10 марта 2011

Что вы предпочитаете?

Вариант 1: Пойти в магазин и посмотреть на различные бренды продукта X и выбрать там один.

Вариант 2. Купив все бутылки продукта X, перетащите их домой,выберите тот, который вам нужен, и выбросьте остальные.

Лично я предпочел бы сэкономить время и деньги, перейдя к варианту № 1

1 голос
/ 10 марта 2011

Если я не ошибаюсь, если в таблице users поле username является первичным ключом, в этом поле будет индекс (кластеризованный или нет), поэтому запрос выполняется по полям username и * 1004.* потратит впустую преимущество индекса и сделает сканирование таблицы;ITOH, запрашивающий только по индексу username, выполнит поиск по индексу, гораздо быстрее.

Конечно, вы можете также создать другой индекс в (username, password), но это не обязательно, и, ИМХО, это пустая трата, так как этоиспользовать только в аутентификации.

Так что, если я прав, я не хочу противоречить всем, но для меня самый оптимизированный способ - это вариант 2.

И, как говорили люди,пожалуйста, не храните пароли в виде простого текста, используйте алгоритм хеширования и сохраняйте хеш, а не пароль.

PD .: Извините за моих бедных англичан.

РЕДАКТИРОВАТЬ: Я не очень хорошо разбираюсь во внутренностях СУБД, поэтому, если я ошибаюсь относительно важности полей запроса для использования индекса или нет, пожалуйста, исправьте меня.

1 голос
/ 10 марта 2011

Второе, и не потому, что я думаю, что оно обязательно более эффективно или что-то в этом роде. Вы должны добавить поле соли в вашу таблицу, хэшировать пароль, добавить соль из возвращенного набора записей и снова засолить его. Тогда вы должны сравнить его с полем пароля.

(Очевидно, что данные в поле пароля должны проходить тот же процесс, когда они хранятся в первую очередь. И вам придется найти хороший способ генерировать соли.)

1 голос
/ 10 марта 2011

Первый, с " с около $user и $password. Последний создает огромный объем трафика между PHP и MySQL - мой плохой, неправильно прочитал запрос, думал, что вы получаете все записи.Кроме того, я очень надеюсь, что ваша база данных настроена таким образом, чтобы этот вызов действовал примерно так:

SELECT * FROM users WHERE username = '$user'  AND password = '".sha1($password.$salt)."'

Хранение незашифрованных паролей - это плохо .

0 голосов
/ 10 марта 2011

Я делаю это так ...

$username = preg_replace("#[^a-zA-Z0-9]#", "", $_POST["username"]);
$password = preg_replace("#[^a-zA-Z0-9]#", "", $_POST["password"]);
$password = sha1($password); // or md5
$sql = mysql_query("SELECT id,password FROM users WHERE username = '$username' AND password = '$password' LIMIT 1");

if(mysql_num_rows($sql) > 0){
    $row = mysql_fetch_assoc($sql);
    setcookie("example", $row["id"]."_".$row["password"], 0, "/", ".example.com");
}
header("Location: http://example.com");
0 голосов
/ 10 марта 2011

1) Не забудьте использовать mysql_real_escape_string($_POST['password']) (так же как и на $_POST['user']), иначе вы столкнетесь с явными пробелами в безопасности.

2) Первое гораздо лучше.Меньше трафика на сервер, и вы никогда не извлекаете пароль из базы данных (что может быть проблемой, если, скажем, кто-то сидит на вашем сервере и отлаживает скрипт PHP, у которого не должно быть доступа к БД).

3) Если вы храните пароли в базе данных, рассмотрите возможность использования некоторого алгоритма хеширования.

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