Я использую JWT-авт сделать RESTful аутентификационный ресурс в моем API. Когда клиентское приложение вызывает ресурс входа в систему, пользователь регистрируется, ваш текущий токен должен быть признан недействительным, и поэтому должен быть создан новый токен.
Но случай, когда текущий токен занесен в черный список TokenBlacklistedException
брошен
Как проверить, находится ли токен в черном списке? Или как правильно реализовать пользовательский «выход из системы»? Я пытаюсь найти на JWT-Auth API источника, но не существует getToken()->isBlacklisted()
или же parseToken()->isBlacklisted()
или какой-нибудь валидатор для его реализации.
Когда-либо токен является недопустимым, parseToken () генерирует исключение TokenBlacklistedException, поэтому метод isBlacklisted является хорошим способом проверить, является ли токен действительным, перед тем как сделать токен недействительным.
ИНФОРМАЦИЯ:
Приведенный ниже код проверяет, является ли полезная нагрузка недействительной. TokenBlacklistedException
если недействительно:
if(
false === \Tymon\JWTAuth\Blacklist::has(
\Tymon\JWTAuth\Facades\JWTAuth::getPayload($token)
)
) {
\Tymon\JWTAuth\Facades\JWTAuth::parseToken()->invalidate();
}
Как проверить, как:
if(false ===\Tymon\JWTAuth\Facades\JWTAuth::parseToken()->isBlacklisted()) {
// invalidate...
}
Вы можете просто уничтожить сеанс на стороне клиента, когда они выйдут из системы, и сделать токен на бэкенде недействительным, вам не нужно использовать черный список.
Технически будет достаточно уничтожить токен на стороне клиента, но для перехвата сеанса также недопустима его аннулирование на бэкэнде.
Если вы лишены законной силы, вам нужно уничтожить токен после того, как вы получите ответ от Laravel.
JWTAuth::invalidate(JWTAuth::getToken())):
Тогда на угловой стороне
function logout()
{
UserService.logout().$promise.then(function() {
$cookieStore.remove('userToken');
// redirect or whatever
});
}
Одним из способов обработки исключений JWT является настройка EventServiceProvider
в Laravel вот как выглядит моя:
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider {
/**
* The event handler mappings for the application.
*
* @var array
*/
protected $listen = [
'tymon.jwt.valid' => [
'App\Events\JWTEvents@valid',
],
'tymon.jwt.user_not_found' => [
'App\Events\JWTEvents@notFound'
],
'tymon.jwt.invalid' => [
'App\Events\JWTEvents@invalid'
],
'tymon.jwt.expired' => [
'App\Events\JWTEvents@expired'
],
'tymon.jwt.absent' => [
'App\Events\JWTEvents@missing'
]
];
/**
* Register any other events for your application.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
//
}
}
Вы зарегистрируете это в своем app.php.
Затем я реализую класс JWTEvents с методами для каждого события.
class JWTEvents extends Event {
// Other methods
public function invalid()
{
return response()->json(['error' => 'Token Invalid'], 401);
die();
}
}
Важно отметить, что мы отлавливаем исключения JWT и возвращаем ответ json с определенным кодом состояния.
С другой стороны, у меня в классе httpInterceptor ловит эти коды состояния http.
angular.module('ngApp')
.factory('httpInterceptor', function($q, $log, $cookieStore, $rootScope, Response) {
return {
request: function(config) {
// Where you add the token to each request
},
responseError: function(response) {
// Check if response code is 401 (or whatever)
if (response.status === 401) {
// Do something to log user out & redirect.
$rootScope.$broadcast('invalid.token');
}
}
}
});
Насколько я понимаю, одна вещь, на которую никто не обращал внимания, это jwt.refresh (он же RefreshTokenMiddleware), используемый для обновления токена.
Теперь, если кто-то, кто хочет выполнить действие выхода из системы, оборачивает метод контроллера в маршрут, подобный
Route::group(['middleware' => ['jwt.auth', 'jwt.refresh']], function()...
наверняка получит новый токен в ответе на выход из системы, следовательно, клиент сможет выполнять новые запросы.
Надеюсь, что это может помочь прояснить эту проблему.