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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41440352/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:02:48  来源:igfitidea点击:

Laravel - force logout of specific user by user id

phplaravelauthenticationlaravel-5

提问by Dani Banai

I use Laravel 5.2.

我使用 Laravel 5.2。

I want to know how can I force a user to logout by id?

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

I'm building an admin panel with the option to dis-active specific user that are currently logged in to the web application.

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

Laravel gives you the this option for current user:

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

Auth::logout()

But I don't want to logout the current user, as I am that Auth user. I need to force logout a specific user by its id. Just like when we login a user with specific id:

但我不想注销当前用户,因为我是那个 Auth 用户。我需要通过特定用户的id. 就像我们用特定的 id 登录用户一样:

Auth::loginUsingId($id);

Is there something like this:

有没有这样的:

Auth::logoutUsingId($id);

回答by sepehr

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

目前,没有直接的方法可以做到这一点。由于StatefulGuard合同及其SessionGuard履行不提供logoutUsingId(),因为他们对做登录

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.

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

Here's a quick implementation.

这是一个快速实现。

1. Add a new field

1. 添加一个新字段

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

让我们向 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...
        });
    }

    // ...
}

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

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

2. Force logout middleware

2.强制注销中间件

Let's create a new middleware:

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

php artisan make:middleware LogoutUsers

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

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

<?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. Register the middleware in HTTP kernel

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

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

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

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 Usermodel to accompany with this functionality:

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

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

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:

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

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

It can be a markForLogoutById($id)method.

它可以是一种markForLogoutById($id)方法。

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

相关讨论
【提案】通过ID
注销用户 删除登录用户时的多条语句

回答by Imad Ullah

Use the setUser to find a soluion

使用 setUser 查找解决方案

  • get current user

       $user = Auth::user();
    
  • logout user you want to, by id

       $userToLogout = User::find(5);
       Auth::setUser($userToLogout);
       Auth::logout();
    
  • set again current user

       Auth::setUser($user);
    
  • 获取当前用户

       $user = Auth::user();
    
  • 通过 id 注销您想要的用户

       $userToLogout = User::find(5);
       Auth::setUser($userToLogout);
       Auth::logout();
    
  • 重新设置当前用户

       Auth::setUser($user);
    

回答by nrkz

I suggest you to override App\Http\Middleware\Authenticate handlefunction with custom check

我建议您使用自定义检查覆盖 App\Http\Middleware\Authenticate处理函数

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