Подтверждение e-mail адреса пользователей для сайта на Yii2.
В данной статье, я расскажу, как можно осуществить проверку указанного посетителем (покупателем и тд.) E-mail адреса. Это полезно при регистрации пользователей или при создании подписки на обновления вашего сайта. Последнее как раз меня и интересовало, т.к. когда мой блог стал достаточно посещаемым, стало «подписываться» много ботов и скрипт стал пытаться рассылать (используя планировщик хостинга) письма на несуществующие адреса.Поэтому пришлось внедрить функционал подтверждения e-mail. Т.к. делал я его для данного блога, созданного с помощью php-фреймворка Yii2, описывать буду на базе Yii2. Хотя, на самом деле, его легко приспособить к чему угодно, включая чистый PHP.
Кратко о процессе реализации.После того, как посетитель вашего сайта или интернет-магазина заполнит форму (регистрации/подписки и др.) ему присваивается специальный код, который с другими данными сохраняется в базу данных, а человеку показывается сообщение, что для окончания регистрации было отправлено письмо на указанный им e-mail со ссылкой подтверждения. Человек, получив данное письмо, переходит по ссылке которая в нем указана. Она ведет на специальную страницу вашего сайта, где скрипт проверяет код (используя GET-параметр адресной строки) и, если такой код присутствует в БД, активирует данную запись (пользователя).
Вот, вкратце и все. Сам код, уже позже, можно использовать, для удаления аккаунта или отписки от сайта. Так же, человек переходит по ссылка на специальную страницу, где скрипт, по данному коду, находит пользователя в БД и удаляет (или деактивирует) его запись.
Реализация.Прежде всего нужно в таблицу, в которой у вас хранятся данные по подписчикам (или зарегистрированным пользователям), например в subscription добавить 2 поля:activation VARHAR 255, по умолчанию = nullstatus tinyint, длина 1, по умолчанию = 0
Для изменения структуры базы данных в Yii2, обычно стоит использовать миграции. Но если вы работаете над собственным сайтом, то можно создать данные поля вручную или выполнив SQL запрос:
В activation будет храниться код, сформированный при регистрации пользователя.В status будет храниться отметка о том, подтвердил ли пользователь свой e-mail (1) или нет (0).При этом, так же, сделаем, чтобы пользователи и боты не подтвердившие регистрацию удалялись автоматически. На это дадим им 5 дней.
Сама форма подписки, лично у меня, вынесена в отдельный виджет и использует функционал Pjax (сохраняет и обновляет данные без перезагрузки страницы). Про форму можно почитать в другой моей статье.
При отправке формы, данные POST-запросом отсылаются на один из контроллеров. У меня это frontend\controllers\SiteController.php который принимает данные и отправляет в модель на обработку. Вот его код (для примера):Тут стоит обратить внимание на строкукоторая вызывает метод activation() в котором генерируется код для данного пользователя и сохраняется в БД вместе с другими данными:
Данный метод стоит разместить в папке с моделями, а именно в модели обрабатывающей таблицу, в которую мы добавляли поля. У меня это common\models\Subscription.php Если функционал по сохранению данных формы вы не выносили в модель, то просто добавьте себе строку по формированию кода в действие контроллера:тут генерируется индивидуальный код используя e-mail пользователя и текущее время сервера.
В следующей же строке вызывается класс и метод отправки сообщения пользователю. Куда передается его e-mail и код для формирования ссылки.
Пример метода отправки (у меня за отправку отвечает отдельный класс MailKsl):не забываем подключать используемые классы в начале файла используя «use».
Тут стоит обратить внимание на строкув ней мы к URL сайта добавляем строку 'activation/', которая будет обозначать действие для контроллера, обрабатывающего полученный код, ну и далее сам код.Пример такой строки:
Если вы и так отсылали письма при регистрации новых пользователей, то просто вставьте в нее ссылку для активации (и код ее формирования), а остальной код данного метода вам не нужен. На данном этапе все данные пользователя сохранены в БД, а ему самому выслано письмо со ссылкой, перейдя по которой он сможет завершить процедуру регистрации (подписки).
Теперь нужно создать страницу, ссылку на которую мы отправляем в письме.Добавляем указанное действие в контроллер frontend\controllers\SiteController.php :
Строкой получаем переданный код. Далее проверяем есть ли такой в БД. Если да – ставим true в поле status и на этом пользователь считается полностью зарегистрированным (или подписанным и тд.) о чем ему выводим соответствующее сообщение. Если же такого кода в БД нет – делаем переадресацию на главную страницу.
Для того, что бы по ссылке http://site.com/activation/107fcc8a246d4f70c5c846ed7f4ae9e1пользователь попадал в контроллер site и метод activation, нужно добавить правило маршрутизации. Для это в файл frontend\config\main.php в массив urlManager, подмассив rules нужно добавитьв начало или по крайней мере до строки
Таким образом мы получим GET параметр с ключом code и значением в качестве переданного кода, который обработает контроллер.
Ну и осталось сделать файл-представление frontend\views\site\activation.php .Пример такого файла:
Вызывая метод registerMetaTag() формируем метатег, указывающий поисковым службам, что это служебная страница и ее не нужно индексировать.У меня на сайте, на этой странице, так же используются блоки и стили Bootstrap + виджеты боковой колонки. Вы сможете настроить вид индивидуально. На этом процесс регистрации/подписки завершен, а именно – пользователь подтвердил свой e-mail о чем свидетельствует значение true (единица) в поле status. Далее, при выборка пользователей, вы просто проверяете наличие данного значения и если в поле status находится значение false – игнорируете таких пользователей.
Что еще не мешало бы, так это сделать автоматическое удаление пользователей (и ботов) которые не подтвердили свой электронный адрес в течении определенного периода, чтобы не накапливать их в таблице. Ниже я приведу такой скрипт.
У меня на блоге, я реализовал отправку уведомлений о новых статьях подписчикам с помощью планировщика (cron), который запускается в определенное время и делает рассылку. Поэтому такое удаление неподтвержденных пользователей я добавил в скрипт рассылки, так же для автоматического выполнения по расписанию. Вы же, если не используете рассылку и планировщик, можете делать удаление таких пользователей при наступлении какого-то события, например при регистрации нового пользователя.В поле addtime таблицы subscription у меня хранится метка времени (в формате Unix) когда текущий пользователь был добавлен.