首页 文章

Laravel - 按用户ID强制注销特定用户

提问于
浏览
3

我使用Laravel 5.2 .

我想知道如何强制用户通过ID注销?

我正在构建一个管理面板,其中包含禁用当前登录到Web应用程序的特定用户的选项 .

Laravel为当前用户提供了此选项:

Auth::logout()

但我不想退出当前用户,因为我是Auth用户 . 我需要通过 id 强制注销特定用户 . 就像我们登录具有特定ID的用户一样:

Auth::loginUsingId($id);

有这样的事情:

Auth::logoutUsingId($id);

1 回答

  • 7

    目前,没有直接的方法来做到这一点;由于StatefulGuard合约及其SessionGuard实施不像login那样提供 logoutUsingId() .

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

    这是一个快速实现 .

    1.添加新字段

    让我们向用户表迁移类添加一个新字段:

    <?php
    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    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] .

    2.强制注销中间件

    让我们创建一个新的middleware

    php artisan make:middleware LogoutUsers
    

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

    <?php
    
    namespace App\Http\Middleware;
    
    use Auth;
    use Closure;
    
    class LogoutUsers
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $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:

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\LogoutUsers::class, // <= Here
        ],
    
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];
    

    它是一个很好的做法,可以为您的 User 模型添加几个API方法以配合此功能:

    • markedForLogout() :检查用户的 logout 标志 .

    • markForLogout() :将用户的 logout 标志设置为 true .

    • unmarkForLogout() :将用户的 logout 标志设置为 false .

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

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

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

    Related discussions
    [Proposal] Log out users by ID
    Multiple statements when logged users are deleted

相关问题