Laravel中的单个会话登录

Jos*_*ski 10 php security authentication laravel

我正在尝试实施一个用户策略,一次只能有一个用户登录.我正试图在Laravel的Auth驱动程序之上构建它.

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

实施会是什么样的?我应该编辑Auth驱动程序中的哪些方法?公共会话密钥存储在哪里?

Alb*_*n N 16

我最近这样做了.

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

如果用户从其他位置登录,则DB中的会话ID将更新,并且"旧"用户将被注销.

我没有改变Auth驱动程序或任何东西,只需在用户登录时将其置于顶部.登录成功时会发生以下情况:

$user->last_session = session_id();
$user->save();
Run Code Online (Sandbox Code Playgroud)

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

if(session_id() != Auth::user()->last_session){
   Auth::logout();
   return true;
}
Run Code Online (Sandbox Code Playgroud)

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


Dar*_*fty 10

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

从创建一个中间件类开始:

php artisan make:middleware CheckSingleSession
Run Code Online (Sandbox Code Playgroud)

添加以下内容:

use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Auth;
Run Code Online (Sandbox Code Playgroud)

并像这样写出句柄:

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);
}
Run Code Online (Sandbox Code Playgroud)

确保您还将它添加到您的用户迁移文件中:

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();
});
Run Code Online (Sandbox Code Playgroud)

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

'checksinglesession' => \App\Http\Middleware\CheckSingleSession::class,
Run Code Online (Sandbox Code Playgroud)

(确保你检查逗号)

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

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


Nic*_*y77 6

使用Laravel 5.6和更高版本:

在LoginController中添加方法

protected function authenticated()
{
    \Auth::logoutOtherDevices(request('password'));
}
Run Code Online (Sandbox Code Playgroud)

在内核

从行中删除评论

\Illuminate\Session\Middleware\AuthenticateSession::class,
Run Code Online (Sandbox Code Playgroud)

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