
php artisan make:auth(подробнее читайте тут) ну а далее уже ее необходимо дорабатывать в зависимости от задач.
По-умолчанию, в Laravel не требуется подтверждение email указанного при регистрации пользователя, а сам он автоматически "логинится" сразу после регистрации. Если для WEB приложения важен реальный электронный адрес, например мы собираемся потом отправлять пользователю сообщения, то такая схема не может устраивать.
В данной статье пример создания функционала подтверждения регистрации пользователя, т.е. ему (на указанный email) будет отправлено сообщение со ссылкой и, пока он по ней не перейдет, не сможет авторизоваться.
Проверено на Laravel версии 5.8.
Сущность и база данных.
В сущность пользователя, файл User.php, добавляем статусы:class User extends Authenticatable { use Notifiable; const STATUS_DELETED = 0; const STATUS_INACTIVE = 9; const STATUS_ACTIVE = 10; …DELETED - может понадобиться в дальнейшем
INACTIVE - статус будет присваиваться сразу после регистрации
ACTIVE - статус будет даваться пользователю подтвердившему свой email
Создаем миграцию:
php artisan make:migration ChangeUsersTable --table=users
В появившийся файл миграции добавляем:
class ChangeUsersTable extends Migration { public function up() { Schema::table('users', function (Blueprint $table) { $table->smallInteger('status')->default(User::STATUS_INACTIVE)->after('remember_token'); $table->string('verify_token')->after('status')->nullable()->unique(); }); DB::table('users')->update([ 'status' => User::STATUS_ACTIVE, ]); } public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('status'); $table->dropColumn('verify_token'); }); } }Всем уже существующим пользователям проставляется STATUS_ACTIVE.
Функционал отправки сообщения о регистрации.
Т.к. подтверждение будет высылаться по email, необходимо создать соответствующий функционал.Генерируем отдельный класс для работы с отправкой писем с помощью консоли:
php artisan make:mail Auth/VerifyMail --markdown=emails.auth.verifyключ --markdown указывает, что будет использоваться формат Markdown для составления шаблона письма. Это упростит работу, т.к. уже есть подготовленные блоки кода в фреймворке. Значением ему указывается путь к шаблону письма (где хотим его разместить), он так же будет сгенерирован.
Создастся файл Mail/Auth/VerifyMail.php наследуемый от Illuminate\Mail\Mailable.
В Laravel каждый тип email-сообщений, отправляемых вашим приложением, представлен классом "mailable".
Нужно его привести к такому виду:
<?php namespace App\Mail\Auth; use App\User; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class VerifyMail extends Mailable { use SerializesModels; public $user; public function __construct(User $user) { $this->user = $user; } public function build() { return $this ->subject('Signup Confirmation') ->markdown('emails.auth.verify'); } }
Шаблон письма resources/views/emails/auth/verify.blade.php
@component('mail::message') # Email Confirmation Please refer to the following link: @component('mail::button', ['url' => route('register.verify', ['token' => $user->verify_token])]) Verify Email @endcomponent Thanks,<br> {{ config('app.name') }} @endcomponent
В ссылке указываем маршрут route('register.verify'), который нужно будет создать для проверки токена т.е. подтверждения регистрации.
Теперь сущность User готова для работы и есть класс с помощью которого будет отправляться сообщение пользователю со ссылкой для подтверждения email.
Изменение логики при регистрации.
Чтобы пользователь не аутентифицировался автоматически после регистрации, чтобы организовать работу с новыми полями из БД (verify_token и status) и чтобы создать функционал отправки письма/подтверждения email, необходимо доработать RegisterController.
Выполнив команду в консоли:
php artisan route:listполучим список зарегистрированных маршрутов. В графе URI находим «register» и действия которые вызываются
- для GET: App\Http\Controllers\Auth\RegisterController@showRegistrationForm
- для POST: App\Http\Controllers\Auth\RegisterController@register
Соответственно форма регистрации открывается переходом по ссылке, а значит методом GET, а данные из нее отправляются на обработку методом POST.
В App/Http/Controllers/Auth/RegisterController.php и подключаемых внутри этого класса трейтах содержится функционал регистрации. Т.к. форма регистрации нас устраивает, ищем действие куда будут переданы данные после ее заполнения. Согласно списка маршрутов, это метод register. В самоом RegisterController такого метода не находим, поэтому переходим в подключаемый трейт RegistersUsers.php. Видим в нем такую строку:
$this->guard()->login($user);т.е. автоматическая авторизация пользователя, от которой нужно избавиться.
Переопределяем его в классе App/Http/Controllers/Auth/RegisterController таким образом:
public function register(Request $request) { $this->validator($request->all())->validate(); event(new Registered($user = $this->create($request->all()))); return redirect()->route('login') ->with('success', 'Check your email and click on the link to verify.'); }
После регистрации пользователь не будет авторизован, а вместо этого перенаправлен на страницу входа с сообщением о необходимости подтверждения email.
Затем меняем метод create, т.к. при создании нового пользователя должен генерироваться случайный токен, а так же статус установим в INACTIVE (хотя это и так значение по-умолчанию для нового пользователя в таблице users):
protected function create(array $data) { $user = User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), 'verify_token' => Str::random(), 'status' => User::STATUS_INACTIVE, ]); Mail::to($user->email)->send(new VerifyMail($user)); return $user; }
Так же тут добавляем отправку сообщения пользователю со сгенерированным ранее классом VerifyMail.
В этом же классе создаем метод который будет выполняться при переходе пользователя по ссылке из письма:
public function verify($token) { if (!$user = User::where('verify_token', $token)->first()) { return redirect()->route('login') ->with('error', 'Sorry your link cannot be identified.'); } $user->status = User::STATUS_ACTIVE; $user->verify_token = null; $user->save(); return redirect()->route('login') ->with('success', 'Your e-mail is verified. You can now login.'); }
По токену будет осуществлен поиск пользователя в БД, затем ему будет установлен статус «активен», а токен обнулен. После этого пользователь будет перенаправлен на страницу входа.
Т.к. в методе create мы добавили 2 аргумента одноименному методу, нужно их указать в сущности User в свойстве $fillable.
User.php
protected $fillable = [ 'name', 'email', 'password', 'verify_token', 'status', ];
Маршрутизация.
Теперь нужно прописать маршрут для действия verify, на которое будет вести ссылка из письма.Добавляем в routes/web.php:
Route::get('/verify/{token}', 'Auth\RegisterController@verify')->name('register.verify');
Изменение логики авторизации.
Осталось сделать, чтобы пользователь не мог "залогиниться" до момента подтверждения своего email.Для этого добавляем метод в App/Http/Controllers/Auth/LoginController.php
public function authenticated(Request $request, $user) { if ($user->status !== User::STATUS_ACTIVE) { $this->guard()->logout(); return back()->with('error', 'You need to confirm your account. Please check your email.'); } return redirect()->intended($this->redirectPath()); }