拉拉维尔中的单会话登录


Single Session Login in Laravel

我正在尝试实施一个用户策略,一次只能有一个用户登录。我正在尝试在 Laravel 的身份验证驱动程序之上构建它。

我想过使用会话驱动程序将会话存储在数据库中,并使每个用户名的键保持不变。由于会话固定,这可能是一个糟糕的实现。

实现会是什么样子?我应该编辑身份验证驱动程序中的哪些方法?通用会话密钥将存储在哪里?

我最近做了这个。

我的解决方案是在用户登录时设置会话值。然后我有一个小班检查存储的会话ID是否与登录的当前用户相同。

如果用户从其他地方登录,数据库中的会话 ID 将更新,"旧"用户将注销。

我没有更改身份验证驱动程序或任何东西,只是在用户登录时将其放在顶部。登录成功后,将发生以下情况:

$user->last_session = session_id();
$user->save();

为了检查会话是否有效,我在下面使用了

if(session_id() != Auth::user()->last_session){
   Auth::logout();
   return true;
}

如您所见,我在用户表中添加了一个名为last_session的列

使用 Laravel 5.6 和更高级版本:

在登录控制器添加方法中

protected function authenticated()
{
    'Auth::logoutOtherDevices(request('password'));
}

在内核中

从行中删除注释

'Illuminate'Session'Middleware'AuthenticateSession::class,

就是这样,该功能现在包含在 Laravel!

我在Laravel 5.7中所做的与Somwang的解决方案类似,但是这将使新登录的用户保持活动状态并注销旧用户。

从创建中间件类开始:

php artisan make:middleware CheckSingleSession

添加以下内容:

use Illuminate'Support'Facades'Session;
use Illuminate'Support'Facades'Auth;

并像这样写出句柄:

public function handle($request, Closure $next)
{
    $previous_session = Auth::User()->session_id;
    if ($previous_session !== Session::getId()) {
        Session::getHandler()->destroy($previous_session);
        $request->session()->regenerate();
        Auth::user()->session_id = Session::getId();
        Auth::user()->save();
    }
    return $next($request);
}

请确保还将其添加到用户迁移文件中:

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('firstName');
    $table->string('lastName');
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
    $table->string('password');
    $table->string('session_id')->nullable();
    $table->rememberToken();
    $table->timestamps();
});

然后你应该能够将其添加到内核中的路由中间件中:project''app''Http''Kernel.php

'checksinglesession' => 'App'Http'Middleware'CheckSingleSession::class,

(确保检查逗号)

我们已经完成了,现在您可以将其用作路由中间件。这样就可以对单个会话进行主动检查。

Route::group(['middleware' => ['auth' ,'checksinglesession'], 'prefix' => 'app'], function () {
    Route::get('/dashboard', 'DashboardController@index')->name('dashboard.index');
});

我的解决方案从 @Albin N 扩展到 Laravel 5。

将"last_session"列添加到表用户中

确保通过将"last_session"添加到用户模型 (User.php) 上的$fillable中来允许此列可填充

protected $fillable = [
    'name', 'email', 'password','last_session'
];

将 authenticated() 函数添加到 App/Http/Controllers/Auth/LoginController 中.php如果找不到它,请确保已运行php artisan make:auth

protected function authenticated()
{
    // Update last_session after logged-in
    User::find(Auth::id())->update(['last_session'=>Session::getId()]);
}

创建新的中间件类php artisan make:middleware SingleSession

if(Auth::check())
{
   // If current session id is not same with last_session column
   if(Auth::user()->last_session != Session::getId())
   {
      // do logout
      Auth::logout();
      // Redirecto login page
     return Redirect::to('login');
   }
}

最后在内核中称你为单会话中间件类.php

protected $middlewareGroups = [
    'web' => [
        'App'Http'Middleware'SingleSession::class,
    ],
    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

每次在执行路由之前,它都会检查就是这样! 快乐编码..!

这个问题要早得多,但有人会通过这些简单的步骤受益。无需进行额外的迁移或其他操作。

第一步是注释掉:

'Illuminate'Session'Middleware'AuthenticateSession::class,App'Http Kernel.php类的台词。

其次,在登录

尝试成功后和重定向之前在登录函数中添加此行: 'Auth::logoutOtherDevices(request('password'));

谢谢。

以下是实现此目的的方法。首先,您需要从 app/Http/Kernel.php 文件中$middlewareGroups属性取消注释 ''Illuminate''Session''Middleware''AuthenticateSession::class 行,因为这是管理 Laravel 中用户会话的中间件。

2-在登录尝试成功后和重定向之前在登录函数中添加此行:''Auth::logoutOtherDevices(request('password'));

use Illuminate'Support'Facades'Auth;
Auth::logoutOtherDevices($password);
   if(Auth::guard('student')->attempt([],$request->rememberme))
    {
        Auth::guard('student')->logoutOtherDevices(request('password'));
        return redirect()->intended('/');  //route('homepage');
    }

https://www.amitmerchant.com/logout-from-everywhere-except-current-device-laravel/

演示https://xpredo.com