通过 Laravel 中的用户 ID 强制注销特定用户

2021-12-18 00:00:00 authentication php laravel laravel-5

我使用 Laravel 5.2,我想知道如何强制用户通过 id 注销.我正在构建一个管理面板,可以选择停用当前登录到 Web 应用程序的特定用户.Laravel 为当前用户提供了这个选项.

I use Laravel 5.2, and I want to know how to force a user to log out by id. I'm building an admin panel with the option to deactivate a specific user that is currently logged in to the web application. Laravel gives you this option for a current user.

Auth::logout()

但我不想注销当前用户,因为我是经过身份验证的用户.因此,我需要通过特定用户的 id 强制退出该用户.就像我们使用特定 id 登录用户一样.

But I don't want to log out the current user, as I am an authenticated user. So I need to force log out of a specific user by its id. Just like when we log in a user with a specific id.

Auth::loginUsingId($id);

有没有类似的东西?

Auth::logoutUsingId($id);

推荐答案

目前,没有直接的方法可以做到这一点;作为 StatefulGuard 合约及其 SessionGuard 实现不像 logoutUsingId()Auth/SessionGuard.php#L507" rel="noreferrer">登录.

Currently, there's no straightforward way to do this; As the StatefulGuard contract and its SessionGuard implementation don't offer a logoutUsingId() as they do for login.

您需要在用户表中添加一个新字段,并在您希望特定用户注销时将其设置为 true.然后使用中间件检查当前用户是否需要强制注销.

You need to add a new field to your users table and set it to true when you want a specific user to be logged out. Then use a middleware to check if the current user needs a force logout.

这是一个快速实现.

让我们为users表迁移类添加一个新字段:

Let's add a new field to users table migration class:

<?php

use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            // ...
            $table->boolean('logout')->default(false);
            // other fields...
        });
    }

    // ...
}

确保在更改迁移后运行 php artisan migrate:refresh [--seed].

Make sure you run php artisan migrate:refresh [--seed] after changing the migration.

让我们创建一个新的中间件:

php artisan make:middleware LogoutUsers

以下是检查用户是否需要被踢出的逻辑:

Here's the logic to check if a user needs to be kicked out:

<?php

namespace AppHttpMiddleware;

use Auth;
use Closure;

class LogoutUsers
{
    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $user = Auth::user();

        // You might want to create a method on your model to
        // prevent direct access to the `logout` property. Something
        // like `markedForLogout()` maybe.
        if (! empty($user->logout)) {
            // Not for the next time!
            // Maybe a `unmarkForLogout()` method is appropriate here.
            $user->logout = false;
            $user->save();

            // Log her out
            Auth::logout();

            return redirect()->route('login');
        }

        return $next($request);
    }
}

3.在HTTP内核中注册中间件

打开app/Http/Kernel.php 并添加中间件的 FQN:

3. Register the middleware in HTTP kernel

Open up the app/Http/Kernel.php and add your middleware's FQN:

/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        AppHttpMiddlewareEncryptCookies::class,
        IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
        IlluminateSessionMiddlewareStartSession::class,
        IlluminateViewMiddlewareShareErrorsFromSession::class,
        AppHttpMiddlewareVerifyCsrfToken::class,
        IlluminateRoutingMiddlewareSubstituteBindings::class,
        AppHttpMiddlewareLogoutUsers::class, // <= Here
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

这是未经测试的代码,但它应该给你一个想法.将几个 API 方法添加到您的 User 模型以配合此功能是一个很好的做法:

It's untested code, but it should give you the idea. It'd be a good practice to add a couple of API methods to your User model to accompany with this functionality:

  • markedForLogout() :检查用户的 logout 标志.
  • markForLogout() :将用户的 logout 标志设置为 true.
  • unmarkForLogout() :将用户的 logout 标志设置为 false.
  • markedForLogout() : Checks user's logout flag.
  • markForLogout() : Sets user's logout flag to true.
  • unmarkForLogout() : Sets user's logout flag to false.

然后在管理方面(我想这是您的情况),您只需要在特定用户模型上调用 markForLogout() 即可在下一个请求中将其踢出.或者,如果模型对象不可用,您可以使用查询构建器来设置标志:

Then on the administration side (I suppose it's your case), you just need to call markForLogout() on the specific user model to kick him out on the next request. Or you can utilize the query builder to set the flag, if the model object is not available:

User::where('id', $userId)
    ->update(['logout' => true]);

它可以是一个 markForLogoutById($id) 方法.

It can be a markForLogoutById($id) method.

相关讨论
[提案] 通过 ID 注销用户
删除登录用户时的多个语句

相关文章