我正在尝试实施一个用户策略,一次只能有一个用户登录。我正在尝试在 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