Повтор кода подтверждения (хак) 2.X

475
Повтор кода подтверждения (хак)

Повтор письма с кодом подтверждения при регистрации.

Столкнулся с ситуацией, когда заметная часть новых пользователей не подтвердили свою почту. Причём названия ящиков у всех выглядят естественными и даже есть такие, которые использовались на другом моём проекте. Все ящики находятся на серверах mail.ru (@mail.ru, @bk.ru). Но при этом до и после ящики других пользователей на том же mail.ru успешно подтверждены, то есть ситуация не строго повторяемая.

Проверка отправки почты из Админки сайта на мой тестовый ящик на @mail.ru показала, что почта доходит за секунды. Тестирование оправки почты на сервисе mail-tester.com даёт оценку "идеально" 9.2/10 - проблем нет, есть несколько возможностей для улучшения. То есть, сам процесс отправки писем работает и это какие-то случайные/временные сбои.

Собственно, проблемы бы и не было, если бы была удобная возможность повторно запросить код подтверждения, как сделано для восстановления забытого пароля. Такую функцию Fuze добавил в версии 2.10, но она работает только если страница с формой ввода кода после первой отправки ещё не закрыта и если прошло уже больше 5 минут. Обычно пользователи не оставляют такие служебные страницы, тем более надолго, а просто закрывают их и продолжают читать сайт, или вообще закрывают браузер. А когда приходит письмо - щёлкают по ссылке. Но даже если повторно открыть страницу с формой ввода кода, то там уже не будет показана ссылка на повторную его отправку. А попытка воспользоваться формой восстановления пароля натыкается на стену: "Пользователь заблокирован". Короче, с точки зрения пользователя - это тупик.

Хорошо бы иметь дополнительную возможность запроса повторной отправки кода пользователями в любое время. По каким-то причинам Fuze считает, что эта функция в "коробке" не нужна, поэтому я сделал своё решение и выкладываю его в блог, может быть оно кому-то пригодится. Никаких новых страниц/форм и подобного. Всё очень просто. Что делает пользователь, если не может зайти в свой аккаунт? Лично я иду на страницу "Забыл пароль" и ищу там ответы или пробую ввести свою почту. Думаю, и другие люди поступают подобным образом. Вот мы эту страницу и немного подправим, сделаем её чуток "умнее".

Так как используется уже готовый экшен Игоря, то всё делается буквально несколькими строчками кода.

В файле \system\controllers\auth\actions\restore.php строку 34
Код PHP:
  1. $errors['email'] = LANG_RESTORE_BLOCK.($user['lock_reason'] ? '. '.$user['lock_reason'] : '');
меняем на строки
Код PHP:
  1. // >> WebMan: Повторная отправка кода подтверждения почты
  2. if ($user['pass_token']) {
  3.  
  4. // Отправляем код подтверждения, если это неподтверждённый пользователь
  5. $_COOKIE['icms']['reg_email'] = $user['email'];
  6. $this->runAction('resubmit');
  7.  
  8. } else {
  9.  
  10. $errors['email'] = LANG_RESTORE_BLOCK.($user['lock_reason'] ? '. '.$user['lock_reason'] : '');
  11.  
  12. }
  13. // << WebMan
При желании также можно подправить константу LANG_RESTORE_NOTICE в файле \system\languages\ru\controllers\auth\auth.php, чтобы получить надпись, как у меня на скрине.

Теперь на странице восстановления пароля, если пользователь подтверждён и разблокирован, то ему на почту как и ранее придёт инструкция по смене пароля. А если он ещё не подтвердил свою почту, то ему будет повторно отправлен код. Заблокированным админом юзерам как и в дефолте будет выдано сообщение о блокировке аккаунта.


UPD 26.08.2018

Можно сделать такую же автоматическую отправку письма с кодом подтверждения и в форме авторизации (идея Александра). Принцип тот же: неподтверждённому пользователю сразу после проверки валидности почты и пароля отправляется повтор письма с кодом, открывается страница верификации кода и показывается уведомление об отправке письма и необходимости подтверждения почты.

Для этого в файле /system/controllers/users/hooks/auth_login.php ПОСЛЕ строки 13
Код PHP:
  1. $this->logoutLockedUser($user);
нужно добавить
Код PHP:
  1. // >> WebMan: Повторная отправка кода подтверждения почты
  2. if ($user['pass_token']) {
  3.  
  4. // Отправляем код подтверждения, если это неподтверждённый пользователь
  5. $_COOKIE['icms']['reg_email'] = $user['email'];
  6. $this->cms_core->getController('auth')->runAction('resubmit');
  7.  
  8. }
  9. // << WebMan

Обратите внимание! Это хаки, при обновлении движка они будут затёрты и их придётся вносить заново.
Google PageSpeed Insights и качество сжатия картинок | Http-ответ 404 для страниц несуществующих тегов (хак)
Комментарии (13)
Александр 12 августа 2018 в 14:01 0
Необходимая вещь, делал такую для первой ветки и буду делать первым делом для второй.

Письма переодически могут не приходить не только на mail.ru и пользователю приходится регистрироваться заново т к восстановить пароль он не может.
WebMan 12 августа 2018 в 14:08 0
У многих пользователей есть только один ящик. И без повтора кода они просто уйдут, так как даже заново зарегистрироваться не смогут на ту же почту. А так хоть какой-то шанс остаётся.
шэльдэ бердэ бельдэ 12 августа 2018 в 21:00 0
Здесь нужен какой-то обратный отсчет, типа "повторный код можно запросить через 46 секунд". Иначе спамеры израсходуют лимит на отправку писем на хостинге. А так, конечно, полезная штука.
WebMan 12 августа 2018 в 21:14 0
Там есть встроенный Игорем лимит: промежуток между запросами не менее 5 минут. Но таймер обратного отсчёта виден только на странице ввода кода при первом запросе сразу после регистрации.
Если в предложенном хаке запросить повтор ранее, чем через 5 минут, получим отлуп "Доступ запрещён". Это, конечно, не красиво и не дружественно для пользователей, но поскольку в "коробку" эта функция не будет входить, я сделал для себя и для блога по минимуму. Для нормальных пользователей этого хватит, а спамеры пусть мучаются, мне их не жалко. smile К тому же, даже вариант Игоря с таймером легко обходится переходом по прямой ссылке экшена.
Fuze 12 августа 2018 в 22:08 0
Всё есть давно.

1. Регистрация



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



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



4. Всё это действует, пока есть время



Зачем городить горбатого к стене, мне неведомо. После регистрации пользователю явно пишется что нужно делать дальше и даже редиректит куда надо.

WebMan:
даже вариант Игоря с таймером легко обходится переходом по прямой ссылке экшена
Не обходится.
WebMan 12 августа 2018 в 22:33 0
Никто не умаляет сделанного тобой, Игорь. Наоборот, ты сделал большое и нужное дело! Частью (экшеном) которого я воспользовался, о чём честно и написал в посте. smile

Но, во-первых, в дефолте если пользователь закрыл страницу ввода кода, то на неё уже нигде нет ссылок. Ему придётся искать её в истории браузера, что вряд ли кто-то будет делать. А "технические" страницы закрывают сразу практически люди, это факт. Во-вторых, ситуации бывают разные, вплоть до регистрации на телефоне, а подтверждение почты делают на компе (или дома / в офисе). В-третьих, пользователь мог попытаться зарегистрироваться повторно, и тогда в куках сохранится уже совсем другой ящик, а на первый email код получить становится невозможно. В-четвёртых, на этом компе может зарегистрироваться пара, например, муж и жена. И если первый человек код не получил, то после регистрации второго уже и не получит.

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

На мой, пользовательский, взгляд, должна быть очевидная и простая возможность повторно запросить код, если он не пришёл. Причём самым интуитивным для обычных людей путём - введя свою почту на страничке восстановления входа ("Забыл пароль"). Что я и реализовал.

WebMan:
даже вариант Игоря с таймером легко обходится переходом по прямой ссылке экшена
Я имел ввиду, что пока тикает таймер, никто не помешает перейти по прямой ссылке экшена. То есть, сам таймер (обратный отсчёт, о котором говорил шэльдэ бердэ бельдэ) легко обходится. А вот уже в самом экшене всё ок, там ты сделал "Доступ запрещён", о чём я и написал выше.
Александр 13 августа 2018 в 13:03 +1
на сколько я понимаю одно дополняет другое, либо должно быть так что ели пользователь ввел при входе не подтвержденную почту то его редиректит на страничку с кодом подтверждения.
WebMan 13 августа 2018 в 13:12 0
Вы понимаете верно, этот хак дополняет уже имеющийся "в коробке" механизм, расширяя механизм восстановления утраченного входа.
Александр:
если пользователь ввел при входе не подтвержденную почту то его редиректит на страничку с кодом подтверждения
Этого я не делал. Идея хорошая, но тогда нужно дорабатывать страницу ввода кода, чтобы отображалась ссылка для повторного запроса кода. Тогда хак станет заметно больше, а мне нужно было быстрое средство. Подумаю над Вашим предложением на досуге...
WebMan 26 августа 2018 в 14:01 +1
Добавил в пост автоматическую отправку письма с кодом подтверждения в форме авторизации при вводе правильной пары почта/пароль неподтверждённым пользователем.
Наконец-то дошли руки. Спасибо за идею, Александр!
Олег Васильевич я 26 августа 2018 в 21:51 0
Спасибо!
Александр 27 августа 2018 в 09:37 0
Вам спасибо, за то что реализовали!
Endroid 12 августа 2018 в 16:47 0
Согласен, вещь нужная! Спасибо!
Алексей Тимофеев 12 августа 2018 в 20:40 +1
Супер хак!
Всем советую...