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

Posted

技术标签:

【中文标题】在 Laravel 中通过用户 ID 强制注销特定用户【英文标题】:Force logout of specific user by user id in Laravel 【发布时间】:2017-05-17 08:36:43 【问题描述】:

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

Auth::logout()

但我不想注销当前用户,因为我是经过身份验证的用户。所以我需要通过其id 强制注销特定用户。就像我们使用特定 id 登录用户时一样。

Auth::loginUsingId($id);

有没有类似下面的东西?

Auth::logoutUsingId($id);

【问题讨论】:

您可以注销并与您id登录。 看看我以前的answer 类似的问题。我得到了 3 次赞成票和 3 次反对票,他们不明白它是如何工作的。如果您不明白它是如何工作的,请在投反对票之前阅读 cmets。 ) 希望这会对你有所帮助。 如果你希望它是实时的,你可以设置你身边的用户的停用(管理面板),并可以使用 websockets 将注销事件推送给特定用户(参见 socket.io) .但是你需要一个节点服务器来实现这个(登录的用户必须通过 websockets 连接到这个节点服务器。管理面板触发一个log out user 命令到节点,然后传递给用户(前端可以强制注销以防万一log out user 事件))如果您不需要实时,您可以在每次页面加载时检查一个 db 字段,如果当前登录的用户已被停用,则注销 太好了,我上面提到的答案又得到了另一个反对票,同时在下面的答案中描述完全相同行为的人得到了 3 个赞成票。顺便说一句,大约一年前我写这个答案时,没有描述任何解决方案,我试图通过多个博客和论坛找到任何东西,所以我的想法是原创的。爱你。 @AlexeyMezenin:冷静点,这里没有人是你的敌人。我读了你的回答;尽管它不值得被否决,但它不是关于实施细节的全面答案。它为 OP 提供了一个可以构建的线索(这是非常好的 IMO)。拥有大约 30k 的代表,您必须知道这里的人们更喜欢像教程一样全面且清晰的答案,而不是正确、最少但不知何故模糊的答案。您在 cmets 中花了很多时间让人们理解您的意思,以及通过添加更好的示例可以做什么。 【参考方案1】:

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

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

这是一个快速实现。

1。添加新字段

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

<?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',
    ],
];

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

markedForLogout() :检查用户的 logout 标志。 markForLogout() :将用户的 logout 标志设置为 trueunmarkForLogout() :将用户的 logout 标志设置为 false

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

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

可以是markForLogoutById($id) 方法。

相关讨论[Proposal] Log out users by IDMultiple statements when logged users are deleted

【讨论】:

【参考方案2】:

使用 setUser 寻找解决方案

获取当前用户

   $user = Auth::user();

通过 id 注销您想要的用户

   $userToLogout = User::find(5);
   Auth::setUser($userToLogout);
   Auth::logout();

再次设置当前用户

   Auth::setUser($user);

【讨论】:

你可以简单地 Auth::logout();用于注销 亲爱的@KashifSaleem!只需 Auth::logout();将注销当前用户,这里我们关心的是注销当前用户以外的用户。【参考方案3】:

我建议你用自定义检查覆盖 App\Http\Middleware\Authenticate handle 函数

if ($this->auth->user()->deleted_at) 
    $this->auth->logout();
    return redirect()->route('login');

【讨论】:

【参考方案4】:

我使用它来注销用户并使用清单锁定他的帐户(可选)的设置和下面的代码,我通过 Ajax 请求做到了:

-在config/session.php中,改为:

'driver' => env('SESSION_DRIVER', 'database'),

-运行 php artisan session:table -run php artisan migrate //创建一个会话表。

-在 .env 文件中:将 SESSION_DRIVER=file 更改为 SESSION_DRIVER=database

现在是编码部分: -在控制器中:

    function ajaxCheckList(Request $request)
    
//                \Log::info($request);
        $user = \App\Models\User::findOrFail($request['user_id']);
        $locked = 0;
        if ($user->locked == 1) 
            $user->locked = 0;
            $locked = 0;
         else 
            $user->locked = 1;
            $locked = 1;
            DB::table('sessions')
                ->where('user_id', $request['user_id'])
                ->delete();
        
        $user->update(['locked' => $locked]);
       

【讨论】:

以上是关于在 Laravel 中通过用户 ID 强制注销特定用户的主要内容,如果未能解决你的问题,请参考以下文章

如果删除状态,Laravel 强制用户注销

检查文件夹是不是已经存在,如果没有在 laravel 中通过 id 创建一个新文件夹

在 Laravel Auth() 中通过电子邮件/电话号码登录

如何在laravel中通过id选择不同表上的关系数据

Laravel - 注销特定用户

Firebase 查询以在 iOS swift 中通过用户 ID 获取特定用户