Yii2 basic, авторизация и регистрация через БД

Yii2 basic, авторизация и регистрация через БД

Простой пример доработки Yii2 basic для авторизации через БД, добавления регистрации и сброса пароля.

Для начала у нас должен быть уже установлен yii2 basic. Как это сделать описано здесь: Как установить Yii 2 basic, краткая инструкция.

Настраиваем соединение с БД в файле /config/db.php и приступаем.

Добавляем авторизацию на сайте в Yii2 basic

Открываем консоль и добавляем миграцию для создания таблицы User

Открываем файл с миграцией /migration/m000000_000000_create_user_table.php и добавляем код создания миграции, особо выдумывать не будем и сделаем такую же как и в версии advanced:

После сохранения правок в файле миграции (копируйте только код методов up() и down()), выполняем ее в консоле:

Правим модель /models/User.php:

Авторизация готова, теперь добавим пользователя для проверки авторизации. Откроем контроллер /controllers/SiteController.php и добавим экшен в конец контроллера который поможет нам добавить пользователя:

Запускаем экшен: site.com/web/index.php?r=site/add-admin и проверяем авторизацию site.com/web/index.php?r=site/login

После успешной аворизации экшен AddAdmin можно удалить за ненадобнастью.

Если вам нужна только авторизация через БД в Yii2 basic, то на этом можно закончить. Если кроме авторизации через БД на сайте нужно добавить регистрацию и восстановление пароля, то продолжим.

Добавляем регистрацию на сайте в Yii2 basic

Для начала создадим модель для форм регистрации, для этого необходимо создать файл /models/SignupForm.php со следующим содержимым:

Далее в /controllers/SiteController.php в use добавляем модель регистрации SignupForm и экшен signup:

Далее необходимо добавить представление для регистрации, добавляем файл /views/site/signup.php со следующим содержимым:

И последнее, что необходимо сделать - это добавить регистрацию в меню. Открываем файл /views/layouts/main.php находим виджет меню и добавляем пункт регистрации, после чего виджет с такого вида:

Теперь у нас есть регистрация и авторизация в Yii2 basic.

Для полноценного функционала осталось только сделать сброс и восстановление пароля.

Добавляем восстановление пароля на сайте в Yii2 basic

Для начала необходимо модифицировать модель /models/User.php и добавить в нее несколько методов для создания и проверки токена сброса пароля:

В итоге модель /models/User.php будет выглядеть следующим образом:

Метод проверки токена сброса пароля isPasswordResetTokenValid используем переменную user.passwordResetTokenExpire для отмены токена сброса пароля, ее необходимо указать в файле /congif/params.php:

Далее необходимо добавить модель формы запроса на смену пароля и модель формы смены пароля. Итого 2 модели. Для начала добавим модель формы запроса на смену пароля /models/PasswordResetRequestForm.php со следующим содержимым:

Модель будет отправлять письмо с подтверждением смены пароля. Для этого она использует 2 лайоута (html и text), html у нас уже есть, необходимо добавить text. Для этого создадим файл /mail/layouts/text.php со следующим содержимым:

Также необходимо создать 2 представляения самого письма (html и text версии). Создадим html версию представления письма, для этого создаем файл /mail/passwordResetToken-html.php со следующим содержимым:

И представление для версии text /mail/passwordResetToken-text.php:

В качестве e-mail отправителя модель указывает e-mail из параметра supportEmail, его тоже нужно добавить. Для этого откройте на редактирование файл /config/params.php и добавьте в массив элемент supportEmail, в итоге получите примерно следующее:

Далее модель для формы смены пароля /models/ResetPasswordForm.php со следующим содержимым:

Теперь добавим экшены для работы с моделями описаными выше. Открываем контроллер /controllers/SiteController.php в use добаляем созданные модели и 2 действия (actionRequestPasswordReset и actionResetPassword):

Далее для этих двух действий необходимо добавить представления, начнем с формы запроса на смену пароля /views/site/passwordResetRequestForm.php:

И представление для формы смены пароля /views/site/resetPasswordForm.php:

Последний штрих, добавим ссылку на сброс пароля в представление формы авторизации, для этого открываем файл /views/site/login.php добавляем ссылку для сброса пароля:

В итоге представление авторизации на сайте будет выглядеть следующим образом:

В итоге мы получили полноценный функционал авторизации через БД, регистрации и сброса пароля в Yii2 basic используя функционал шаблона Yii2 advanced.

Авторизация в Yii2 по e-mail вместо username

Для авторизации на сайте мне больше нравится использование e-mail пользователя в качестве логина вместо ника, по умолчанию в yii2 используется ник в качестве логина. Исправить это довольно просто.

Начнем с модели /models/User.php, в ней необходимо добавить метод findByEmail для поиска пользователя по e-mail:

Далее в моделе /models/LoginForm.php меняем своойство (переменную) $username на $email в методе rules добавляем правило обработки e-mail [['email'], 'email'] и в методе getUser() меняем вызов User::findByUsername($this->username) на User::findByEmail($this->email), вот что получится:

И последнее, в представлении /views/site/login.php меняем поле username на email:

Если у вас есть вопросы или предложения по улучшению кода описанного в статье пишите в комментариях. Я всегда открыт к конструктивному диалогу

Рекомендуемые Комментарии

Авторизируемся по username или email.Немного меняем функцию findByEmail

Егор, у вас ошибка в разделе "Добавляем восстановление пароля на сайте в Yii2 basic". В настройках SiteController.php в экшанах надо прописать

Об остальном могу сказать одно: это один из лучших гайдов по этой теме) Остальные модули и иностранные гайды устарели и не работают (лично в моем случае). А ваш заработал! Спасибо Вам огромное!

Да, точно надо заменить или переименовать вьюхи, спасибо исправлю

Хочу выразить благодарность автору, действительно хорошая во всех качествах статья

Лучшая статья по теме регистрации/авторизации на Yii2. Все понятно и без заморочек

Очень рад, что пригодилось

Invalid Parameter – yii\base\InvalidParamExceptionWrong password reset token.

Invalid Parameter – yii\base\InvalidParamExceptionWrong password reset token.

1. in C:\xampp\htdocs\curch\models\ResetPasswordForm.phpat line 39

30313233343536373839404142434445464748 if (empty($token) || !is_string($token))

$this->_user = UserIdent::findByPasswordResetToken($token); var_dump($this->_user);

/** * @inheritdoc */ public function rules()

2. in C:\xampp\htdocs\curch\controllers\UserController.php at line 188– app\models\ResetPasswordForm::__construct('3DVWpAbz1qRVQwGcct_iPW=Tqk7KF1lR. ')

182183184185186187188189190191192193194 * @return mixed * @throws BadRequestHttpException

4. in C:\xampp\htdocs\curch\vendor\yiisoft\yii2\base\InlineAction.php at line 55– call_user_func_array([app\controllers\UserController, 'actionResetPassword'], ['3DVWpAbz1qRVQwGcct_iPW=Tqk7KF1lR. '])

5. in C:\xampp\htdocs\curch\vendor\yiisoft\yii2\base\Controller.php at line 154– yii\base\InlineAction::runWithParams(['token' => '3DVWpAbz1qRVQwGcct_iPW=Tqk7KF1lR. '])

6. in C:\xampp\htdocs\curch\vendor\yiisoft\yii2\base\Module.php at line 454– yii\base\Controller::runAction('reset-password', ['token' => '3DVWpAbz1qRVQwGcct_iPW=Tqk7KF1lR. '])

7. in C:\xampp\htdocs\curch\vendor\yiisoft\yii2\web\Application.php at line 100– yii\base\Module::runAction('user/reset-password', ['token' => '3DVWpAbz1qRVQwGcct_iPW=Tqk7KF1lR. '])

8. in C:\xampp\htdocs\curch\vendor\yiisoft\yii2\base\Application.php at line 375– yii\web\Application::handleRequest(yii\web\Request)

9. in C:\xampp\htdocs\curch\web\index.php at line 12– yii\base\Application::run()

6789101112 require(__DIR__ . '/../vendor/autoload.php');require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');

$config = require(__DIR__ . '/../config/web.php');

$_GET = [ 'token' => '3DVWpAbz1qRVQwGcct_iPW=Tqk7KF1lRfDi_1484317888',];

$_COOKIE = [ '_csrf' => '24f3675abcc58d277899972e6ccab69404d6802894a54194938ab5c46db4a214a:2:', 'PHPSESSID' => 'sqng1fni89b52hbsdgkci2h0h0', '_gat' => '1', '_ga' => 'GA1.1.1939233386.1479989658',];

Якщо зробити так

То на виході отримаю

Здається мені що проблема десь в UserIdent, який не з прикладу

Поставив більний час, бо помітив, що відрізнявся часовий пояс,

Date: Fri, 13 Jan 2017 17:26:09 +0100

Subject: Password reset for My Application

From: My Application robot <robot@devreadwrite.com>

Content-Type: text/plain; charset=utf-8

Follow the link below to reset your password:

Content-Type: text/html; charset=utf-8

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org=

<meta http-equiv=3D"Content-Type" content=3D"text/ht=

<p>Follow the link below to reset your password:</p>

перевіряв Юзер клас, але там аж нічого такого не має. Методи по відновленню пароля із Вашого прикладу. Єдине- замінені назви полів

Попробуйте в классе (и в БД) увеличить длину токена

Потому-что кажется мне что он больше 32 символов (3DmAQhybfVaYIJ4_ffZ1fbMdckXxtI8Err_1484318712)

Если я правильно понял то это

Что в базе? Такой же токен как и в письме?

Я не знаю як правильно, але я роюлю для двох полів одне і теж значення.Омеження 'access_token'], 'string', 'max' => 255 поставив всюди 255 симовлів для всіх полів і в тому числі в бд.

Коли йде реєстрація

Токен в листі 3Dgn2ieBLFUfVYPoixTt4r=P1_5-BWxcm5e_1484337672

Навіть, якщо вручну прибирати в посиланню http://localhost/curch/web/user/reset-password?token=3Dgn2ieBLFUfVYPoixTt4r=

P1_5-BWxcm5e_1484337672 занчення 3Dб всеодно не працює

В дебагері видно тільки ось

Я ваш пароль спрячу на всякий случай)

Так мы будем долго пробовать, если есть желание то отправьте на почту egor@кодер.укр архив с проектом и полный дамп базы, попробую помочь, но ничего не обещаю.

Если сами разберетесь, то пишите сюда что да как.

Всё верно пишет Микола. Есть проблема с восстановлением пароля. И у вас не может работать корректно. По коду всё верно. где проблема - непонятно.

Просто в письме дописывает в начало токена 3D , в остальном всё хорошо

Дякую усім за допомогу, а особливу автору. . Проблеми були банальні - в базі даних поле містило менше 255 символів, тому новий пароль просто не поміщався. Все інше як у статті.

Хорошая статья, все понятно и работает с первого раза, спасибо за сэкономленное время

Все работает. Самая адекватная статья по текущей теме

Материал изложен более чем достойно. Сайт однозначно в закладки.

У меня была ошибка при логине с включёным чекбоксом "Remember me"

Вылечилось добавлением в файле User.php.

Это просто ошибка в статье или я что-то не так делаю?

Скачал с репозитория, проверил, все работает без:

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

Создаем БД с именем local_yii2_site_com, логин root, пароль пустой, если нужно изменить название БД, логин или пароль, то создаем необходимые и перед командой yii migrate правим файл соединения с БД: /config/db.php

Далее открываем консоль и выполняем следующие команды:

Перезапускаем веб сервер.

Добавляем пользователя (логин: admin, пароль: admin): http://yii2-auth.loc/web/index.php?r=site/add-admin

В модели вы генерируете исключения на инвалидные токены, всё классно, ошибки ловятся.

Вопрос, что с ними делать-то в итоге? Если пользователь попытается повторно сбросить пароль по старому токену или подменит его в ссылке, то сайт покажет ошибку с описанием исключения.

Нам же нужно как-то исключение обработать и показать пользователю ошибку, мол, запроси сброс пароля заново.

Делайте на свое усмотрение, например отдавайте 404 ошибку или другую страницу со своим описанием, это пример который не претендует на идеальность)

Все вроде сделал правильно, но при /site/request-password-reset кидает на главную а сендмейл ничего не шлет..

Проверьте спам, работу отправки писем с сервера или пример из репозитория

пример из репозитория. в денвере в папке появляется файл -sess_7a4a. с содержимым tmp __flash|a:1:success|s:42:"Check your email for further instructions."; и все. в папке !sendmail писем не появляется.

Файл config/web.php закоментируйте строку:

Получаем примерно следующее:

После чего письма должны появиться.

Вот пример письма:

Его лучше открывать с помощью любой почтовой программы для нормального внешнего вида

Можно заменить отправку со стандартной на smtp, тогда точно будет отправляться, есть даже пример как это сделать: Yii 2, отправка почты (сообщения) через SMTP

теперь при переходе по ссылке из письма для сброса пароля вылезло вот это:

Namespace declaration statement has to be the very first statement in the script

in G:\openserver\OpenServer\domains\yii.test\models\ResetPasswordForm.php at line 2

Огромнейшее вас спасибо! Очень долго не мог сделать авторизацию на yii, но благодаря вашему примеру написал авторизацию через стим.

Статья отличная все работает, но как получить на странице данные текущего пользователя?

Т.е. если допустим делать личные кабинеты, у каждого свои данные, человек авторизовался, а дальше? Писать его id и login в сессию и таскать везде? Как вообще используя данный тут в статье код можно это сделать на Yii2 ?

Решил проблема. Всегда когда начинаю тормозить задаю вопрос и через пару минут нахожу ответ :)

Может кто-то также как и я только начинает знакомство с этим замечательным фреймворком, и для таких же вот ответ:

вызываем где надо и получаем необходимые данные )

password reset token не должно автоматически добавляет в бд при регистрации пользователья?

Где тут лайкнуть?

Ваш комментарий лучше любого лайка

После ввода емэйла для смены пароля на ту же страницу /site/request-password-reset

В БД для пользователя в поле password_reset_token какой то токен создается. Но не переход на страницу уведомления об успешном запросе ни письмо со ссылкой не приходит.

В runtime\debug\mail насыпало несколько .eml в которых содержатся те самые ожидаемые письма, но даже если взять ссылку из них и открыть в браузере - 404.

#908 - этот коммент пробовали?

Вообще такой секции нет. Добавление блока mailer не помогло. Мне достался такой сайт, но письма он каким то образом отправляет. В YII новичек, даже не представляю куда копать.

зы статья супер!

Статья то что нужно давно искал, не понимаю почему из коробки это не внедрили сразу .

Но у меня возникла проблема с внедрением данной формы на все страницы сайта ( в сайт бар) чтобы человек не переходил на лишнее страницы а мог сразу с любой страницы за логиниться . Не могу понять вываливается такая ошибка "Call to a member function isAttributeRequired() on null"

Слишком мало информация для определения проблемы. Возможно здесь найдете ответ Yii Framework, AJAX авторизация во всплывающем (модальном) окне (это не Yii2, но принцип тот же)

Спасибо за совет почитаю, ту ошибку я исправил. не правильно объявил виджет. Теперь выводится на сайте как надо форма. Но при авторизации идет редерект на стартовую и авторизация не проходит . Код LoginFormWidget.php сам views

ну и вызов виждета

А просто авторизация работает? На странице, без всплывающего окна.

Да простоая авторизация работает

Ну тогда надо понять проблема после/до или вовремя авторизации:

на var_dunp($model->getErrors); die();

еще больше ошибок "Getting unknown property: app\models\LoginForm::getErrors"

Вот правильный вариант (вроде):

В любом случае $model->login() возвращает false, надо смотреть что ему там не нравиться

Есть смысл еще посмотреть что лежит в Yii::$app->request->post(), может там не все параметры передаются

Последний код рабочий и выводи OK

Если это не поможет, то вариантов у меня больше нет:

Я тоже уже не знаю с чего подступится к решению этой проблемы ( Но все равно спасибо вы единственный кто откликнулся на вопрос. Последний код выдает ошибку

Все из-за спешки, меняем $this->refresh() на Yii::$app->controller->refresh():

И я только сейчас заметил? loginformWidget.php, должно быть так:

Object of class yii\web\Response could not be converted to string

Интересно, завтра попробую сделать авторизацию в модальном окне, напишу инструкцию. Вроде подводных камней быть не должно

Тогда ждем, мне тоже интересно

спасибо. Уже даже интересно в чем же моя ошибка. Я только начал изучать Yii2

Здравствуйте, поставил сея дополнение, все отлично работает. Но вот нужно получить ид текущего авторизированного юзера. И никак не могу. В главном контроллере

О боже, полтора часа ломал голову, пока не понял что не авторизирован!

"Откроем контроллер /controllers/SiteController.php и добавим экшен в конец контроллера который поможет нам добавить пользователя"

чтобы экшен сработал надо добавить в шапку use "app\models\User;", хз у кого какая версия, но у меня этой записи в basic шаблоне не было.

в use добаляем созданные модели и 2 действия (actionRequestPasswordReset и actionResetPassword):

"для отмены токена сброса пароля, ее необходимо указать в файле /congif/params.php:"

Далее для этих двух действий необходимо добавить представления, начнем с формы запроса на смену пароля /views/site/passwordResetRequestForm.php

И представление для формы смены пароля /views/site/resetPasswordForm.php

нет таких файлов )) на github в этой папке лежат requestPasswordResetToken.php и resetPassword.php соотв.

Строки 45 - 47. Зачем нам проверять существование юзера, если у нас в валидации стоит проверка?

При попытке запустить site.com/web/index.php?r=site/login выдаёт ошибку:

Cannot redeclare class app\models\LoginForm

Статья хорошая. Не подсккажите это регистрация на три роли (админ и зарегистрированный пользователь, все остальные Гость) или на две (Админ-Пользователь, все остальные Гость)?

возникла проблема на этапе восстановления пароля по токену. Токен, который генерируется и сохраняется в БД отличается от токена высылаемого в письме, соответственно при переходе возникает ошибка "Wrong password reset token."

В БД токен 2EWpxPBAjZV4Wcrdb2tfnZ6Kwg5KipqE_1534249101

В письме 3DfnWvNPOdPuRLQZRt-Upi-KzQJHqlwGjw_1534246579

Я так понял, что тут не ограничивается длина токена размером VARCHAR(255), как реализовать это ограничение?

Реализовал через a.binetsky@ya.ru generateRandomString($length = 10), токены, все равно не совпадают

Свел генерацию токена, вовсе до time(), все равно в письме 3Diy5AHC9Ex5b5oalcfucuNa5yFQm1yq20_1534253550

Нет такого файла в папке views/site/requestPasswordResetToken.php. Откуда его взять?

Подтверждаю актуальность. До сброса пароля (я это не реализовывал) все работает. Автору респект за качественный материал.

Автор, спасибо за статью! Помогла настроить авторизацию на сайте Yii2 через БД

📎📎📎📎📎📎📎📎📎📎