Laravel 护照阻止用户使用相同的凭据一起登录

Laravel passport prevent user to login together with the same credential

我使用 Laravel Passport 允许我的手机调用 laravel api 以使用 laravel 身份验证。

我最近发现一个问题 laravel passport 允许同一用户从多个设备登录。有什么办法可以防止同一个用户同时登录其他设备吗?

我找到了一种使用 Laravel Passport 注销的方法,但我不知道如果我使用

这是否是最好的方法
$request->user()->token()->revoke()

每当用户尝试登录时。

您可以挂钩 AccessTokenCreated 事件,然后在您的侦听器中您可以撤销任何现有令牌。

将这些 events/listeners 添加到您的 EventServiceProvider

'Laravel\Passport\Events\AccessTokenCreated' => [
    'App\Listeners\RevokeExistingTokens',
],

然后使用php artisan make:listener RevokeExistingTokens

创建监听器

然后在 handle 函数中:

$user = User::find($event->userId);

$user->tokens()->offset(1)->get()->map(function ($token) {
    $token->revoke();
});

这将删除除刚刚创建的用户令牌之外的所有用户令牌。

非对称答案不仅正确,但在某些版本的 MySQL 中,"offset" 方法可能存在问题,因此您可以在 "handle" 函数中执行此操作:

 Token::where('id', '!=', $event->tokenId)
    ->where('user_id', $event->userId)
    ->where('client_id', $event->clientId)
    ->delete();

考虑@Lucas Dalmarco 对@atymic 关于MySQL "offset" 命令问题的回答的评论。这是一个可以实施的解决方案。

$user = User::find($event->userId);

$user->tokens()->limit(PHP_INT_MAX)->offset(1)->get()->map(function ($token) {
    $token->revoke();
});

Laravel Passport 已经为此目的提供了事件。请查看document

Passport 在颁发访问令牌和刷新令牌时引发事件。您可以使用这些事件来修剪或撤销数据库中的其他访问令牌。如果愿意,您可以在应用程序的 App\Providers\EventServiceProvider class:

中将侦听器附加到这些事件
/**
 * 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',
    ],
];