Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2009.10.11;
Скачать: [xml.tar.bz2];

Вниз

Проверка логина на PHP + Postgres   Найти похожие ветки 

 
Пит   (2009-08-11 18:20) [0]

При авторизации пользователь вводит логин, по которому нужно найти его запись в БД.

Нужно сделать данный поиск регистро-независимым.

Например, один из вариантов решения проблемы - использование при поиске пользователя оператора LIKE.
При этом возникает вопрос грамотного экранирования, в частности символов "%" и "_". Может еще каких.

Кто делал проверенную реализацию данного действия, поделитесь?


 
Ega23 ©   (2009-08-11 18:30) [1]

Select UserID from Table where Upper(Login) = Upper(Введённое имя пользователя)

З.Ы.
Ты меня ОЧЕНЬ удивил.


 
palva ©   (2009-08-11 18:30) [2]


> Например, один из вариантов решения проблемы...

А о какой проблеме идет речь? Зачем нужно использование LIKE ?

Вы ищете запись пользователя vova, но в этой записи нет поля со значением "vova", так что ли? Тогда объясните, как устроена запись пользователя vova.


 
Пит   (2009-08-11 18:44) [3]

Ega23, это стопроцентно будет работать в связке PHP + Postgres с русскими и английсками буквами, кодировка UTF?


 
Пит   (2009-08-11 18:45) [4]

проблема в том, что я не могу протестировать.
Сейчас работает на LIKE - поэтому я знаю, что на LIKE работает. Но есть обозначенная проблема со спец. символами.

Нужно заменить сразу и чтобы работало.


 
Пит   (2009-08-11 18:48) [5]


> where Upper(Login) = Upper(Введённое имя пользователя)

есть подозрение, что не самый оптимальный вариант. Впрочем, LIKE, конечно, не оптимальнее.

Интересно, какой оптимальный. Дополнительная колонка, где имя пользователя забито, но в определенном регистре?


 
Ega23 ©   (2009-08-11 19:17) [6]


> Интересно, какой оптимальный.


Оптимальный - то, что ты получил, перевести в Upper, и уже это подсунуть в запрос.
А так - ну не миллионже пользователей у тебя? А деже если и миллион, то ID найти - ну 2 секнды займёт. Это копейки.
Хотя для клинических случаев - да, задавать 2 поля, в одном (индексированом) - сразу в Upper (или Lower, это как уж тебе удобнее), в другом - As Entered


 
Anatoly Podgoretsky ©   (2009-08-11 19:32) [7]

> Ega23  (11.08.2009 19:17:06)  [6]

А еще лучше соответствующею регистрно независимую локализацию.


 
Ega23 ©   (2009-08-11 19:36) [8]

> А еще лучше соответствующею регистрно независимую локализацию.

Честно - не понял идею.
Какая локализация?


 
Anatoly Podgoretsky ©   (2009-08-11 20:19) [9]

> Ega23  (11.08.2009 19:36:08)  [8]

Я не знаю поддерживает ли локализации Postgre, поэтому ответ по MS SQL - серверу/базе/таблице/полю можно указать одну из нескольких локализаций, пареметр называется Collation - для русского языка это может быть Cyrillic_CI_AS - регистно независимая, но акценто зависимая, их много, обычно выбирается эта. И все сравнения, преобразования пойдут в соответствии с ней. WHERE Name="ИвАноВ"; сработает одинаково и для ИВАНОВ/иванов - не надо никаких UPPER


 
Ega23 ©   (2009-08-11 22:07) [10]


> Cyrillic_CI_AS


А... Всё, догнал.
Только вот заковыка, у меня может быть 3 языка: английский, русский и казахский. И пароль я на казахском вводить буду.


 
palva ©   (2009-08-11 22:51) [11]

Пароль в отличие от логина принято сравнивать с учетом регистра. Так надежней.


 
Ega23 ©   (2009-08-11 22:59) [12]


> Пароль в отличие от логина принято сравнивать с учетом регистра.
>  Так надежней.


Пардон, а какой дурак пароль в явном виде в БД хранит?  :)


 
palva ©   (2009-08-11 22:59) [13]


> Ega23 ©   (11.08.09 22:07) [10]

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

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


 
Ega23 ©   (2009-08-11 23:02) [14]


> А использование национальных алфавитов чревато искажениями,
>  поскольку возможны разные кодировки.


UTF-8 - и нет проблем. Как Collation на столбец (таблицу, базу), так и на html-страницу.


 
jack128_   (2009-08-11 23:07) [15]


> <Цитата>
>
> Ega23 ©   (11.08.09 18:30) [1]
>
> Select UserID from Table where Upper(Login) = Upper(Введённое
> имя пользователя)


http://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0


 
Anatoly Podgoretsky ©   (2009-08-11 23:16) [16]

Ну естественно, что динамические запросы, вместо использования параметров используют только дураки.
Я думаю, что приведеный код только образец.


 
palva ©   (2009-08-11 23:16) [17]


> UTF-8 - и нет проблем

Ага, попробуй с разными левыми браузерами. Сбойнёт и покажет страницу в другой кодировке. Если страница авторизации оформлена графикой, то даже незаметно будет. А пароль отошлется в той кодировке, в которой показана страница. Лучше ограничить пользователей, чтоб не иметь потом головной боли.


 
Anatoly Podgoretsky ©   (2009-08-11 23:18) [18]


> Ega23 ©   (11.08.09 22:07) [10]

Ниже palva все объяснил, нужны ограничения, особенно на пароль, поскольку возможны искажения.


 
Ega23 ©   (2009-08-11 23:26) [19]


> jack128_   (11.08.09 23:07) [15]


Жека, это то, что php-скрипт делает. Запускать такое get/post-параметром - я до такого не додумался бы даже тогда, когда про SQL-injection ничего не знал.
Выглядеть это будет как-то так:

http://localhost/login.php?LID=1&Login=Vasya&pwd=pupkin
А вот в самом скрипте - уже и хэширование пароля, и выполнение самого запроса.


 
Дмитрий С ©   (2009-08-12 07:55) [20]


> Ega23 ©   (11.08.09 19:17) [6]
>
>
> > Интересно, какой оптимальный.
>
>
> Оптимальный - то, что ты получил, перевести в Upper, и уже
> это подсунуть в запрос.
> А так - ну не миллионже пользователей у тебя? А деже если
> и миллион, то ID найти - ну 2 секнды займёт. Это копейки.
>
> Хотя для клинических случаев - да, задавать 2 поля, в одном
> (индексированом) - сразу в Upper (или Lower, это как уж
> тебе удобнее), в другом - As Entered

Я в похожем случае, чтобы не создавать индекс по имени пользователя добавил столбец с CRC32(UPPER(`username`)), и проиндексировал его.
И запрос примерно такой
WHERE UPPER(`username`) = UPPER(".....") AND `username_crc` = CRC32(UPPER("......")).

Индекс для username не стал делать, потому что имена были вроде таких:
"DomainName\UserName"


 
Пит   (2009-08-12 09:51) [21]


> А так - ну не миллионже пользователей у тебя?

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

И так я не понял ответа на свой вопрос, озвученного в [3]


 
Ega23 ©   (2009-08-12 09:51) [22]

WHERE UPPER(`username`) = UPPER(".....") AND `username_crc` = CRC32(UPPER("......")).

А НАФИГА?????
Если ты CRC32 от Upper уже хранишь, нафига тогда UPPER(`username`) = UPPER(".....") проверять????  Либо одно либо другое - лишнее.


 
Ega23 ©   (2009-08-12 09:56) [23]


> И так я не понял ответа на свой вопрос, озвученного в [3]


Я с PHP не особо знаком (так, 3 дня пощщупал в своё время), поэтому его особенностей работы с UTF не представляю.
С Postgres проблем не было.


 
Пит   (2009-08-12 10:07) [24]


> Если ты CRC32 от Upper уже хранишь

по-моему, бред. Не такой уж невероятный процент ошибки будет.


 
Пит   (2009-08-12 10:07) [25]

ведь при любых раскладах UPPER будет работать быстрее LIKE"а?


 
Ega23 ©   (2009-08-12 10:24) [26]


> ведь при любых раскладах UPPER будет работать быстрее LIKE"а?


Спорный вопрос. От СУБД зависит. В твоём случае - мало исходной информации. Но по-идее - должен быстрее работать, особенно если индексировано.

Блин, только сейчас допёр: а как ты LIKE используешь???


 
palva ©   (2009-08-12 10:29) [27]

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

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

Совет: найдите какую-нибудь умную книжку и сделайте в соответствии с ней. Либо разберитесь досконально что и для какой цели применяется.


 
Ega23 ©   (2009-08-12 10:36) [28]


> Зачем имя пользователя хэшировать?


Ну, один из способов хранения (если его нигде выводить не надо пользователю).
Unique-index, хэш от Upper от юзернаме.


 
palva ©   (2009-08-12 10:47) [29]

Ну если выводить не надо... Тогда может быть...

Хотя тоже как-то странно не выводить. Обычно вверху всегда висит "Привет user". Пользователь должен иметь возможность в любой момент проверить, что он находится под своим аккаунтом. А если он отходил на пару минут, а кто-то сел за компьютер вышел из его аккаунта и зашел под своим. Тогда вернувшийся пользователь может отправить приватную информацию в чужую базу данных.


 
Ega23 ©   (2009-08-12 10:49) [30]


> Хотя тоже как-то странно не выводить.


Не, на самом деле, при большом (реально большом, не 100.000) количестве записей, можно хранить UserName и Hash(Upper(UserName)). Выводить первое, искать по второму.
Хотя, ИМХО, мартышкин труд, по Upper быстрее отыщется (если только не массовая заливка... :))) )


 
Anatoly Podgoretsky ©   (2009-08-12 11:35) [31]

> Ega23  (12.08.2009 10:24:26)  [26]

Ну что бы и Иванов и Иванова без разницы кто могли пройти аутентификацию друг за друга.


 
Ega23 ©   (2009-08-12 11:40) [32]


> Ну что бы и Иванов и Иванова без разницы кто могли пройти
> аутентификацию друг за друга.


Угу, не сразу сообразил.


 
Anatoly Podgoretsky ©   (2009-08-12 11:40) [33]

> Ega23  (12.08.2009 10:49:30)  [30]

Hash мартышкин труд, и Upper мартышкин труд если база регистро независима. Upper нужен если СУБД слабая и нет встроеной регистро независимости.


 
Ega23 ©   (2009-08-12 11:45) [34]


> Upper нужен если СУБД слабая и нет встроеной регистро независимости.


Эта "встроенность" регулируется настройками. Где-то может быть включено, а где-то - выключено. И тогда приплыли.


 
Anatoly Podgoretsky ©   (2009-08-12 11:49) [35]

> Ega23  (12.08.2009 11:45:34)  [34]

Регистро зависимость обычно включается ключевым словом Collation (или ее эквивалентами) и гранулируется вплоть до поля. Возможно есть сервера без поддержки Collation - тогда затруднительно, но это экзотика, все промышленые СУБД имеют такую возможность.


 
palva ©   (2009-08-12 11:50) [36]


> Ну что бы и Иванов и Иванова без разницы кто могли пройти
> аутентификацию друг за друга.

Хорошая идея. В двенадцати стульях была такая троица: Галкин, Палкин и Залкинд. Для них неплохо бы завести единый логин. LIKE рулит.


 
Anatoly Podgoretsky ©   (2009-08-12 11:51) [37]

%kin%


 
palva ©   (2009-08-12 11:54) [38]

_alkin%


 
Дмитрий С ©   (2009-08-12 18:15) [39]

Завтра попробую на мускуле проверить как быстрее будет:)



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2009.10.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.006 c
15-1249582655
TUser
2009-08-06 22:17
2009.10.11
Комнатное растение никому не надо?


3-1228129957
zorik
2008-12-01 14:12
2009.10.11
Firebird 2.0 to Firebird 1.5


15-1249924835
@!!ex
2009-08-10 21:20
2009.10.11
Где найти книг во вселенной BattleTech?


10-1160379486
cloix
2006-10-09 11:38
2009.10.11
Реализация методов IDispatch


8-1198056476
Klim
2007-12-19 12:27
2009.10.11
Image+Rect





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский