Регистрация, активация и авторизация в Laravel (часть 2)
Доброго времени суток. В данной статье мы продолжим рассмотрение регистрации, активации и авторизации в Laravel. Так в первой части мы рассмотрели регистрацию пользователей в Laravel. И при регистрации пользователю высылалось сообщение на введенный им email адрес со ссылкой для активации. Продолжим.
Как вы помните, при регистрации пользователю на email приходило сообщение вида: «Для активации аккаунта перейдите по ссылке: http://lesson.loc/auth/activate?id=<id пользователя>&code=<сгенерированный код>». Теперь наша задача в контроллере AuthController создать метод, который будет сверять переданные данные с данными хранящимися в нашей таблице codes и при их активировать аккаунт пользователя.
Создание метода активации пользователя
Для начала, давайте создадим маршрут для метода activate, который будет активировать пользователя. Откроем файл:
app/Http/Controllers/routes.php
И добавим в него следующее правило:
Route::get('auth/activate','Auth\AuthController@activate');
Отлично, теперь перейдем в контроллер:
app/Http/Controllers/Auth/AuthController.php
И создадим в нем метод activate:
public function activate(Request $request) { $res = Code::where('user_id',$request->id) ->where('code',$request->code) ->first(); if($res) { //Удаляем использованный код $res->delete(); //активируем аккаунт пользователя User::find($request->id) ->update([ 'activated'=>1, ]); //редиректим на страницу авторизации с сообщением об активации return redirect()->to('auth/login')->with(['message' => 'ok']); } return abort(404); }
Давайте немного поясним данный метод. В начале мы ищем в таблице с кодами запись соответствующую user_id равную $request->id и code = $request->code. Если запись не найдена, то вызываем ошибку 404 — страница не найдена и пользователю возвращаем страницу 404. Если запись найдена, то удаляем ее из таблицы с кодами, активируем соответствующего пользователя и перенаправляем на страницу авторизации с сообщением об успешной активации. По редиректам в Laravel вы можете почитать в моей статье «Redirect (перенаправление) в Laravel 5».
Единственное, что мы не сделали в прошлый раз – это не отредактировали в модели User поля, которые разрешено массово заполнять (более подробно об этом можно почитать в официальной документации по Laravel ) давайте это исправим.
Откроем модель User и исправим свойство $fillable следующим образом:
protected $fillable = ['activated', 'email', 'password'];
Создание формы авторизации
И так метод getLogin контроллера AuthController возвращает нам отображение формы авторизации. Давайте создадим форму авторизации. Для этого в директории с видами, в папке auth создадим файл login.blade.php и добавим в него следующий код:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Авторизация</title> <link href="{{ asset('/css/bootstrap.css') }}" rel="stylesheet"> <script src="{{ asset('/js/jquery.js') }}" type="text/javascript" charset="utf-8" ></script> <script src="{{ asset('/js/bootstrap.js') }}" type="text/javascript" charset="utf-8"></script> </head> <body> <div class="container"> <nav class="navbar" role="navigation"> <ul class="nav navbar-nav"> <li class="active"> <a href="{{ url('auth/register') }}">Регистрация</a> </li> </ul> </nav> {{--Ошибки--}} @if ($errors->has()) <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="alert alert-danger" role="alert"> <button class="close" aria-label="Close" data-dismiss="alert" type="button"> <span aria-hidden="true">×</span> </button> <ul> @foreach($errors->all() as $error) <li> {{{ $error }}}</li> @endforeach </ul> </div> </div> </div> @endif {{--Успех--}} @if (Session::has('message')) <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="alert alert-success" role="alert"> <button class="close" aria-label="Close" data-dismiss="alert" type="button"> <span aria-hidden="true">×</span> </button> {{ Session::get('message') }} </div> </div> </div> @endif <form role="form" method="post" action="{{ url('auth/login') }}"> {!! csrf_field() !!} <div class="form-group"> <label for="email">Email</label> <input type="email" class="form-control" id="email" placeholder="Email" name='email'> </div> <div class="form-group"> <label for="password">Пароль</label> <input type="password" class="form-control" id="password" placeholder="Пароль" name="password"> </div> <button type="submit" class="btn btn-default">Войти</button> </form> </div> </body> </html>
Отлично давайте проверим что у нас получилось. Проверим таблицу users:
Нет записей, проверим таблицу codes:
Тоже нет записей, отлично. Переходим на страницу регистрации и регистрируем нового пользователя.
Регистрация прошла успешно
Теперь проверим таблицу users:
Появился пользователь. И обратите внимание на поле «activated». Пользователь не активирован.
Давайте посмотрим таблицу codes:
Хорошо, видим запись для пользователя с id = 1. Попробуем активировать пользователя по ссылке. Как помните у нас включена симуляция отправки писем, само письмо записывается в лог.
При переходе по ссылке должна произойти активация пользователя, из таблицы codes удалена соответствующая запись и перекинуть нас на страницу авторизации с сообщением «Ок».
Отлично, нас перекинуло на страницу авторизации с сообщением. Давайте проверим таблицу codes, там не должно быть записей.
Теперь проверим активизировался ли пользователь, смотрим таблицу users:
Да, все получилось, в поле «activated» стоит 1.
Осталось сделать авторизацию.
Авторизация пользователя в Laravel.
Как мы помним за регистрацию и авторизацию отвечает контроллер AuthController. За авторизацию – метод postLogin. Пропишем роут к данному контроллеру.
Route::post('auth/login','Auth\AuthController@postLogin');
Сам метод уже реализован в Laravel, но он нам не подходит. Поэтому переопределим его.
Открываем контроллер AuthController и прописываем:
public function postLogin(Request $request) { if (Auth::attempt(['email' => $request->email, 'password' => $request->password,'activated' => 1])){ return "Редирект в кабинет"; } return redirect()->to('auth/login'); }
И не забываем вставить
use Illuminate\Support\Facades\Auth;
Ну вот и все. Теперь при успешной авторизации будет надпись «Редирект в кабинет», а при не успешной – нас перебросит обратно на страницу авторизации.
Проверим. Все работает. Теперь давайте попробуем зарегистрировать нового пользователя и не проходя активации попробовать авторизоваться им. Не получилось.
Это все, что я хотел показать в этих двух статьях. И небольшое замечание: первое мы не рассмотрели защиту роутов с помощью middleware. Защиту надо делать обязательно. Второе мы организовали простой способ активации. Обязательно нужно учитывать срок действия кода, а также сделать чистку таблицы codes (удалять просроченные коды). И в третьих желательно сделать срок жизни не активированного пользователя и чистку таблицы users от таких пользователей. В ближайшее время я опишу как создать artisan команды и мы с вами создадим две команды, которые будут удалять просроченные кода и не активированных пользователей. Так, что следите за обновлениями блога.
А на этом все.