3
votes

Dans Laravel, existe-t-il un moyen de supprimer les anciens jetons de passeport révoqués / expirés

J'utilise le passeport Laravel pour la mise en œuvre de l'API. Lorsque l'utilisateur se connecte au site, il crée un nouveau jeton, les anciens sont révoqués, car ces enregistrements augmentent de jour en jour.

Est-il possible de supprimer les jetons de passeport expirés?

Merci d'avance.


1 commentaires

Vous voudrez peut-être vérifier ce lien github.com/laravel/passport/issues/629


5 Réponses :


2
votes

Vous devriez utiliser des travaux CRON pour cela. Faites simplement une commande qui une fois par jour (par exemple) interroge la table DB pour les jetons qui sont révoqués, et supprimez ces enregistrements.

php artisan make:command DeleteRevokedTokens

il générera ce fichier dans app/Console/Commands . Écrivez cette logique Eloquent dans cette méthode de commande handle() . Donnez à cette commande un nom dans la variable $signature et une description dans la variable $description .

Ensuite, allez dans app/Console/Kernel.php et dans la méthode schedule() , ajoutez une ligne comme celle-ci $schedule->command('yourCommandNameThatYouWroteInSignatureVariableOfYourCommand')->dailyAt('00:00');

C'est ça. Il ne vous reste plus qu'à activer vos CRON jobs . C'est inutile sur le développement, mais doit sur la production. Pour tester votre commande, écrivez simplement dans le terminal php artisan yourCommandNameHere , où yourCommandName est la variable $signature de cette commande. Ainsi, lorsque vous l'écrivez, il l'exécutera. Le travail Cron ne gérera que cette commande est automatiquement lancée lorsque vous l'avez définie dans app/Console/Kernel.php .


1 commentaires

Avez-vous vraiment besoin d'ajouter une autre couche de complexité à cette tâche simple? Vous pouvez simplement écrire la logique dans le rappel $schedule->call()



3
votes

Un peu tard, mais de toute façon, quelqu'un pourrait le trouver utile.

Au lieu de configurer une tâche CRON, vous pouvez utiliser les événements de passeport pour cela. Passport émet des événements lorsque le jeton d'accès est créé et lorsque le jeton d'actualisation est créé. Tout ce que vous avez à faire est d'enregistrer ces événements dans EventServiceProvider et d'appeler l' php artisan event:generate

/**
 * Handle the event.
 *
 * @param  RefreshTokenCreated  $event
 * @return void
 */
public function handle(RefreshTokenCreated $event)
{
    \DB::table('oauth_refresh_tokens')
        ->whereDate('expires_at', '<', now()->addDays(1))
        ->delete();
}

Ensuite, dans App\Listeners\PruneOldTokens vous pouvez supprimer tous les autres jetons que l'utilisateur possédait auparavant:

/**
 * Handle the event.
 *
 * @param  AccessTokenCreated  $event
 * @return void
 */
public function handle(AccessTokenCreated $event)
{
    Token::where([
        ['user_id', $event->userId],
        ['id', '<>', $event->tokenId]
    ])->delete();
}

N'oubliez pas d'importer Laravel\Passport\Token en haut.

Remarque: je supprime également les jetons d'actualisation expirés sur l'événement créé par le jeton d'actualisation. Ajoutez simplement ceci dans l'écouteur pour l'événement créé par le jeton d'actualisation. De cette façon, chaque fois qu'un nouveau jeton d'actualisation est créé pour un utilisateur, tous les jetons expirés sont supprimés.

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Laravel\Passport\Events\AccessTokenCreated' => [
        'App\Listeners\RevokeOldTokens',
    ],
    'Laravel\Passport\Events\RefreshTokenCreated' => [
        'App\Listeners\PruneOldTokens',
    ],
];


3 commentaires

C'est la pire façon de le faire. La création de jetons n'a rien à voir avec l'expiration / la révocation de jetons ... pourquoi utiliseriez-vous l'événement AccessTokenCreated et RefreshTokenCreated pour déclencher le nettoyage? Pouvez-vous imaginer la quantité de spam que vous allez créer (en particulier dans un système occupé). Ne me laissez pas commencer sur le fait que la plupart des clients créeront de nouveaux jetons ET refresh_token à chaque session de requête ...


Comment pouvez-vous dire que l'expiration / la révocation n'a rien à voir avec les événements AccessTokenCreated et RefreshTokenCreated ?! De toute évidence, vous ne comprenez pas ce que fait ce code. Si vous l'avez fait, vous verrez que lorsque de nouveaux access_token sont créés pour un utilisateur, ALORS tous les autres jetons pour CE MÊME utilisateur sont supprimés. Et quant au refresh_token , il supprime tous les refresh_token qui ont expiré d'un jour. De plus, cette même approche est utilisée dans les documents Laravel .


L'affiche souhaite supprimer les jetons expirés / révoqués. Ainsi, il peut ajuster la logique de l'auditeur comme il le juge approprié dans son cas. Je lui montre juste un moyen de le faire sans utiliser de tâches cron (comment cela fonctionne dans mon cas). Et si vous souhaitez que plusieurs appareils soient connectés en même temps, vous pouvez ajuster la logique pour prendre en charge cela. La chose cruciale ici est que vous pouvez utiliser les événements Passport natifs pour ce faire et que vous n'avez pas nécessairement besoin d'utiliser le travail cron. Mais à la fin de la journée, tout dépend de ce qui fonctionne dans votre cas.



4
votes

Le style Laravel

Nous utiliserons cette commande pour purger les jetons révoqués et expirés:

<?php

namespace App\Console;

class Kernel extends ConsoleKernel
{
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('passport:purge')->dailyAt('03:00');
    }
}


0 commentaires

1
votes

Commande de la console artisanale:

passeport artisan php: purge


0 commentaires

0
votes

Cela déconnectera l'utilisateur et supprimera le jeton en même temps.

public function logout ()
{
    $tokenRepository = app('Laravel\Passport\TokenRepository');
    $user = auth('api')->user();

    if ($user) {
        $tokenRepository->revokeAccessToken($user->token()->id);
        $user->token()->delete();

        return response()->json(['status', 'Logged Out']);
    } else {
        return response()->json(['status', 'Already Logged Out']);
    }

}


0 commentaires