В 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.