Делаем аутентификацию в REST API
В Laravel по-умолчанию встроена аутентификация пользователя с использованием форм и php-сессий. Однако такой подход неприменим для авторизации при работе через RESTful API. Дело в том, что один из принципов работы RESTful API заключается в том, что сервер между запросами не хранит никакой информации о текущем пользователе.
Согласно этому принципу вся информация для выполнения запроса должна приходить в самом запросе. Конечно, передавать в каждом запросе логин и пароль пользователя, является нарушением всех правил безопасности, даже несмотря на повсеместно используемый защищенный протокол https.
Вместо этого в запрос передается некая сгенерированная сервером последовательность символов - токен. Токен генерируется таким образом, чтобы его было практически невозможно подобрать в приемлемое время. Кроме того, у токена выставляется время действия, по истечении которого токен становится недействительным, и требуется его перевыдача.
Принцип работы аутентификации с использованием токенов следующий:
- Клиент посылает серверу логин и пароль пользователя
- Сервер проверяет валидность переданных данных, и, если с ними все в порядке, генерирует токен доступа и возвращает его клиенту
- Клиент сохраняет в своем хранилище выданный токен и использует его при каждом запросе к серверу
Для упрощения разработки аутентификации для Laravel создан официальный пакет Passport, который позволяет не только производить аутентификацию в API, но и реализует полноценную авторизацию с использованием открытого протокола OAuth2.
Попробуем с его помощью сделать простую аутентификацию пользователя через API.
Первым делом устанавливаем пакет Passport:
composer require laravel/passport
После установки пакета необходимо выполнить миграцию, чтобы создались необходимые для работы passport таблицы в базе данных:
php artisan migrate
После выполнения миграции, passport необходимо проинициализировать. При этом создадутся необходимые записи для генерации токенов в ранее созданных таблицах. Это делается с помощью команды:
php artisan passport:install
Следующим шагом необходимо добавить трейт HasApiTokens в наш класс User:
namespace App\Models; use Laravel\Passport\HasApiTokens; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use HasApiTokens, Notifiable; ... }
Этот трейт добавит к классу пользователя дополнительные методы для работы с токенами.
В файле config/auth.php в разделе guards следует поменять значение драйвера для api:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
Первоначальные настройки сделаны. Осталось создать контроллер и методы регистрации и аутентификации. В папке App\Http\Controllers\Api создаем контроллер:
php artisan make:controller Api/AuthController
В контроллере создаем необходимые методы.
Регистрация пользователя
В этом методе создается объект пользователя по переданным параметрам (имя, email, пароль), сохраняется в БД и возвращается сообщение об у спешной регистрации.
public function register(Request $request) { $user = User::create(array_merge( $request->only('name', 'email'), ['password' => bcrypt($request->password)] )); $user->save(); return response()->json([ 'message' => 'Вы успешно зарегистрированы' ], 200); }
Вход в систему
Метод идентифицирует пользователя по переданным email и паролю и если все в порядке, генерирует токен доступа, устанавливает дату действия токена и возвращает его в json.
public function login(Request $request) { $credentials = $request->only('email', 'password'); if (!Auth::attempt($credentials)) { return response()->json([ 'message' => 'Неверно указан логин или пароль', 'errors' => 'Unauthorised' ], 401); } $token = Auth::user()->createToken(config('app.name')); $token->token->expires_at = Carbon::now()->addDay(); $token->token->save(); return response()->json([ 'token_type' => 'Bearer', 'token' => $token->accessToken, 'expires_at' => Carbon::parse($token->token->expires_at)->toDateTimeString() ], 200); }
Выход из системы
В этом методе токен просто отзывается у авторизованного пользователя.
public function logout(Request $request) { $request->user()->token()->revoke(); return response()->json([ 'message' => 'Вы успешно вышли из системы', ]); }
Маршруты для аутентификации
После реализации методов контроллера аутентификации создадим соответствующие маршруты в файле /routes/api.php:
Route::group(['namespace' => 'Api'], function () { Route::post('register', 'AuthController@register'); Route::post('login', 'AuthController@login'); Route::post('logout', 'AuthController@logout')->middleware('auth:api'); });
Два первых маршрута - register и login работают для неавторизованных пользователей. Третий маршрут logout работает через middleware auth - только для авторизованных пользователей. Для запросов по этому маршруту следует передавать в запросе заголовок с токеном доступа:
Authorization: Bearer erJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
Теперь все готово. Можно регистрировать нового пользователя через вызов /api/register, передав параметры name, email и password, авторизоваться через вызов /api/login, передав email и password, и выходить из системы через вызов /api/logout.
Комментарии (0)