MySQL объединяет не возвращающие строки - PullRequest
0 голосов
/ 03 июня 2010

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

Однако у меня возникла проблема с запросом ... с одной стороны, он будет возвращать строки, только если это был тот же пользователь, к которому они пытались войти ранее. Мне нужно, чтобы это был любой пользователь. Во-вторых, независимо от того, что я использую: LEFT JOIN, RIGHT JOIN, INNER JOIN или JOIN, он не будет возвращать идентификатор пользователя, если в login_attempts.

нет строки для пользователя
SELECT COUNT(`la`.`id`), 
       `u`.`id`
FROM `users` AS `u` 
LEFT JOIN `login_attempts` AS `la` ON `u`.`id` = `la`.`user_id`
WHERE `u`.`username` = 'admin' 
  AND `la`.`ip_address` = '127.0.0.1' 
  AND `la`.`timestamp` >= '1'

Вот вывод из DESC login_attempts

Field       Type                Null    Key Default Extra
id          int(10) unsigned    NO      PRI NULL    auto_increment
user_id     int(10) unsigned    NO      MUL NULL     
ip_address  varchar(15)         NO      MUL NULL     
timestamp   int(10)             NO          NULL     

Этот запрос делает то же самое, за исключением того, что даже не выбирает идентификатор, если в логин-строке есть соответствующая ему строка:

SELECT COUNT(`la`.`id`), 
       `u`.`id`
FROM `users` AS `u` 
LEFT OUTER JOIN `login_attempts` AS `la` ON `u`.`id` = `la`.`user_id` 
  AND `la`.`ip_address` = '127.0.0.1' 
  AND `la`.`timestamp` >= '1'
WHERE `u`.`username` = 'admin' 

Ответы [ 2 ]

3 голосов
/ 03 июня 2010

Не используйте объединение, а разделяйте запросы. Выполните подсчет количества попыток в одной и возврат идентификатора пользователя в другой:

sql 1:

select count(id) from login_attempts where ip_address="<ipaddress>"

sql 2:

select id from users where username="<username>"

Если вы действительно настаиваете на использовании объединений, для которых, я думаю, это действительно не нужно:

select count(login_attempts.id), users.id
from users
cross join login_attempts
where users.username="<username>"
and login_attempts.ip_address="<ipaddress>"

Что я тоже считаю неэффективным.

0 голосов
/ 03 июня 2010

Попробуйте перевести ip_address и timestamp в состояние соединения. Вам нужно внешнее соединение с login_attempts.

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