На прошедшей неделе один из клиентов поставил задачу приделать к его Интернет-магазину форму восстановления пароля, но такую, чтобы с ней было удобно и просто работать конечному пользователю и чтобы все это было безопасно и с помощью данной функции пароль к учетной записи мог изменить только владелец учетной записи, а не любой желающий.
Итак, предположим, что у нас есть адрес электронной почты пользователя и его логин. В WebEngine авторизация происходит одновременно и по логину, и по адресу электронной почты, а вот в Интернет-магазине, о котором идет речь, для авторизации можно использовать только логин. Соответственно, для восстановления пароля мы будем использовать логин и адрес электронной почты, так как логин в нашем магазине используется при комментировании лотов, благодаря чему доступен широкой массе читателей, которые могут периодически вводить логин в форму восстановления пароля. Восстановить ничего, конечно, им не удастся, но вот пользователю будет регулярно приходить письмо о восстановлении пароля, которое в скором времени будет попадать в папку, предназначенную для спама, куда в скором времени направится и вся остальная почта с нашего сайта. Использовать только адрес электронной почты также не стоит, так как электронная почта может быть взломана, после чего ее адрес пройдется по таким вот страничкам восстановления. В данном случае оптимальным вариантом я считаю введение одновременно и логина, и адреса электронной почты. Но что дальше? Вот вводит пользователь логин и электронную почту, и что дальше?
А дальше мы отправим пользователю письмо на электронную почту. Можно воспользоваться также сервисами отправки SMS, если у нас есть номер мобильного телефона пользователя, однако это штука не совсем полезная: во-первых, только 10% наших клиентов готовы платить за отправку кодов подтверждения по SMS; во-вторых, пользователь в качестве контактного номера телефона может указать и городской, на который наше уведомление не придет никогда (в конце концов у пользователя просто-напросто может не быть мобильного телефона, либо же телефон у него будет, к примеру, американский, а в Америку отправлять сообщения будет дорого и эта функция, скорее всего, в SMS-биллинге будет отключена); в третьих, вспомните «Приват24» и его коды авторизации, которые могут приходить через полдня после пополнения. Что же будет в нашем письме пользователю? Единственное, чего там никогда не будет ― это пароля, высланного в открытом виде в качестве напоминания. Пароля в чистом виде вообще не должно быть в базе данных сайта, если его владельцы хоть немного заботятся о безопасности своих посетителей. Пароли должны шифроваться и храниться в базе в зашифрованном виде без возможности восстановления, а сверка при авторизации происходит путем шифрования по той же схеме введенного пользователем пароля и пароля, хранящегося в базе данных. Короче говоря, если Вам когда-либо придет в письме с напоминанием пароль в открытом виде, то я советую таким сервисом больше не пользоваться, либо придумать специальный пароль только для него (дабы в случае взлома базы данных этого сайта злоумышленники не получили пару логин-пароль, при помощи которой будут взломаны учетные записи на всех остальных сайтах).
В письме пользователю у нас может быть только два варианта содержания: либо сформированный в случайном порядке новый пароль, либо ссылка, по клику на которой пользователь попадет на страницу, где он сможет ввести собственный пароль на замену забытому. Первое я лично не уважаю, так как сгенерированный пароль сразу же забывается, а менять его, как правило, при первом после восстановления входе лень, благодаря чему через пару дней (либо когда истечет срок действия cookies и пользователю снова придется авторизоваться) пользователь снова воспользуется функцией восстановления пароля. В случае, если будет использоваться второй вариант, на странице можно будет организовать дополнительные уровни безопасности. К примеру, попросить пользователя дать ответ на секретный вопрос, который он вводил при регистрации на сайте. Стоит отметить, что ответы желательно должны быть регистронезависимыми, так как для нас важнее правильность самого ответа, а не формат, в котором он нам предоставлен (а вот паролям лучше всего быть регистрозависимыми ― тогда можно будет смело написать простенькое слово «забором» и радоваться, что глупые роботы никогда не додумаются, какие буквы в слове мы сделали заглавными, а какие строчными). Поле для ввода нового пароля можно предоставлять уже на этой странице, а можно и на следующей, на которую пользователь попадет лишь в том случае, если верно ответит на секретный вопрос. И вот тут небольшое развлекательное отступление: когда-то давно я был участником одного городского форума, на котором процедура восстановления пароля была реализована почти так же, как я сейчас расписываю, за исключением одного: на странице с формами для ввода нового пароля в качестве подтверждения нужно было указать старый пароль, который мы, кстати, запамятовали. Аккаунты с забытыми или потерянными паролями на том форуме никогда не восстанавливались, поэтому у некоторых участников было сразу по пять учетных записей с несколькими тысячами сообщений на каждом.
Ну что ж, с самой процедурой мы разобрались, теперь давайте рассмотрим ограничения. Прежде всего, мы должны ограничить пользователей от подбора паролей к их учетным записям. Сделать это можно несколькими способами и желательно использовать их при этом одновременно.
1. Ограничение на количество попыток авторизации по IP-адресу. Это нужно на случай, если хитрый робот будет подбирать пароль не только к одной учетной записи, а сразу к целому списку. Не жалейте для этого места в базе данных ― это очень полезная штука. К примеру, мы можем блокировать функции авторизации для IP-адреса в том случае, если в течение часа с него было осуществлено 25 попыток авторизации с разными логинами.
2. Ограничение на количество попыток ввода пароля для учетной записи. Позволит защитить конкретную учетную запись от подбора пароля. Действует просто: если пользователь неверно ввел пароль, то следующий раз он сможет ввести его только через десять, к примеру, минут. В итоге подбор пароля будет сильно усложнен и скорее всего, никто не станет им заниматься.
А теперь я, возможно, удивлю любителей разнообразной защиты от роботов. Captcha совершенно не нужна ни на странице авторизации, ни на странице восстановления пароля. А все из за того, что что предыдущих двух ограничений вполне достаточно для усмирения роботов, в то же время, графические коды подтверждения ― это уже прошлый век. Если раньше роботы были глупыми и умели заполнять только формы, то теперь они уже без проблем проходят даже проверку reCaptcha и теперь использование этих кодов ― пустая нагрузка на сервер. Такую же нагрузку создаст и робот, пытающийся заполнить форму несмотря на блокировку, поэтому никакой необходимости в таких кодах подтверждения в современном мире не вижу.