Как получить token для авторизации api в Laravel Sanctum из HTTP-заголовка, отличного от Authorization
Laravel Sanctum предоставляет очень простой путь для организации авторизации api мобильных приложений (да и не только мобильных) через token авторизации. Но что делать, если приложение уже разработано и оно отправляет token авторизации в HTTP заголовке, отличном от Authorization. Настроек Sanctum для этого просто нет, как и, собственно, во всем Laravel. Мне предстояло получить token из заголовка HTTP X-Auth-Token. Чтобы это сделать, пришлось создать собственный класс защитника и собственный класс Service Provider.
Для начала создадим свой собственный SanctumServiceProvider. Он будет расширять родной класс Laravel\Sanctum\SanctumServiceProvider и перекрывать единственный метод createGuard.
<?php
namespace App\Extentions;
use Illuminate\Auth\RequestGuard;
use Laravel\Sanctum\SanctumServiceProvider as SSP;
class SanctumServiceProvider extends SSP
{
/**
* Register the guard.
*
* @param \Illuminate\Contracts\Auth\Factory $auth
* @param array $config
* @return RequestGuard
*/
protected function createGuard($auth, $config)
{
return new RequestGuard(
new SanctumCustomGuard($auth, config('sanctum.expiration'), $config['provider']),
request(),
$auth->createUserProvider($config['provider'] ?? null)
);
}
}
Далее наш Service Provider нужно зарегистрировать. Можно это сделать с помощью artisan, если до этого не было регистрации родного ServiceProvider.
php artisan vendor:publish --provider="app\Extentions\SanctumServiceProvider"
Если родной (Laravel\Sanctum\SanctumServiceProvider) ServiceProvider уже зарегистрирован, то можно тогда нами разработанный ServiceProvider зарегистрировать в config/app.php, добавив строчку в массив providers:
...
'providers' => [
...
App\Extentions\SanctumServiceProvider::class
...
],
...
В коде нашего ServiceProvider мы используем наш собственный защитник SanctumCustomGuard. Нам нужно создать собственного защитника и перекрыть в нем один метод getTokenFromRequest, заменив в нем способ получения token'а из HTTP-заголовка.
<?php
namespace App\Extentions;
use Illuminate\Http\Request;
use Laravel\Sanctum\Sanctum;
use Laravel\Sanctum\Guard;
class SanctumCustomGuard extends Guard
{
/**
* Get the token from the request.
*
* @param \Illuminate\Http\Request $request
* @return string|null
*/
protected function getTokenFromRequest(Request $request)
{
if (is_callable(Sanctum::$accessTokenRetrievalCallback)) {
return (string) (Sanctum::$accessTokenRetrievalCallback)($request);
}
return $request->header('X-Auth-Token', '');
}
}