Laravel Jetstream - 停止多设备登录
Laravel Jetstream - Stop multiple device login
我正在使用 Laravel 8 和 Jetstream。如我所见,我的用户可以从多个设备登录我的网站并访问内容。所以我想阻止他们。如果用户成功登录到第二台设备,则他们将从第一台设备注销。简而言之,用户一次可以从一台设备访问我的内容。没有多设备登录。
在我早期使用 Laravel Breeze 的项目中,我很容易完成它,因为那里有控制器。在 Laravel Jetstream 中,我很困惑。哪位好心人,求推荐。
--- 更新 ------
试过了,但没有成功。不过,我的用户可以从两个不同的设备登录
在 FortifyServiceProvider 中:
public function boot()
{
Fortify::createUsersUsing(CreateNewUser::class);
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->email.$request->ip());
});
RateLimiter::for('two-factor', function (Request $request) {
return Limit::perMinute(5)->by($request->session()->get('login.id'));
});
//This is what I added
Fortify::authenticateUsing(function (Request $request) {
$user = User::where('email', $request->email)->first();
if ($user &&
Hash::check($request->password, $user->password)) {
auth()->logoutOtherDevices($request->password);
return $user;
}
});
}
您只需在 app/Http/Kernel.php
文件中启用注释的 AuthenticateSession
中间件即可。
/**
* 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\Session\Middleware\AuthenticateSession::class, // --> this one
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
登录后,您应该注销其他会话。
/**
* Invalidate other sessions for the current user.
*
* The application must be using the AuthenticateSession middleware.
*
* @param string $password
* @param string $attribute
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function logoutOtherDevices($password, $attribute = 'password')
我尝试了很多其他方法,最后得出的结论是,如果您使用 Laravel Jetstream,“logoutOtherDevices
”将永远无法工作。如果您应用我不想要的非标准 hack,它可能会起作用。
因此,就我而言,我以自己的方式解决了它。用户成功登录后,他们将被重定向到他们的仪表板页面。在仪表板控制器中,我检查会话 table(在数据库中)并删除用户的会话记录,跳过他们当前设备的会话。
任何面临此类问题的人都可以使用我的 100% 工作方法。这是例子-
$this_device_session = \Session::getId(); //user's current session id is stored
//check in sessions table. If record exist then delete it skipping the current session.
if(DB::table('sessions')->where('id','!=',$this_device_session)->where('user_id',Auth::user()->id)->exists()) {
//delete their session
DB::table('sessions')->where('id','!=',$this_device_session)->where('user_id',Auth::user()->id)->delete();
}
return view('dashboard'); //user's dashboard page or any page you want
我正在使用 Laravel 8 和 Jetstream。如我所见,我的用户可以从多个设备登录我的网站并访问内容。所以我想阻止他们。如果用户成功登录到第二台设备,则他们将从第一台设备注销。简而言之,用户一次可以从一台设备访问我的内容。没有多设备登录。 在我早期使用 Laravel Breeze 的项目中,我很容易完成它,因为那里有控制器。在 Laravel Jetstream 中,我很困惑。哪位好心人,求推荐。
--- 更新 ------
试过了,但没有成功。不过,我的用户可以从两个不同的设备登录
在 FortifyServiceProvider 中:
public function boot()
{
Fortify::createUsersUsing(CreateNewUser::class);
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->email.$request->ip());
});
RateLimiter::for('two-factor', function (Request $request) {
return Limit::perMinute(5)->by($request->session()->get('login.id'));
});
//This is what I added
Fortify::authenticateUsing(function (Request $request) {
$user = User::where('email', $request->email)->first();
if ($user &&
Hash::check($request->password, $user->password)) {
auth()->logoutOtherDevices($request->password);
return $user;
}
});
}
您只需在 app/Http/Kernel.php
文件中启用注释的 AuthenticateSession
中间件即可。
/**
* 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\Session\Middleware\AuthenticateSession::class, // --> this one
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
登录后,您应该注销其他会话。
/**
* Invalidate other sessions for the current user.
*
* The application must be using the AuthenticateSession middleware.
*
* @param string $password
* @param string $attribute
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function logoutOtherDevices($password, $attribute = 'password')
我尝试了很多其他方法,最后得出的结论是,如果您使用 Laravel Jetstream,“logoutOtherDevices
”将永远无法工作。如果您应用我不想要的非标准 hack,它可能会起作用。
因此,就我而言,我以自己的方式解决了它。用户成功登录后,他们将被重定向到他们的仪表板页面。在仪表板控制器中,我检查会话 table(在数据库中)并删除用户的会话记录,跳过他们当前设备的会话。
任何面临此类问题的人都可以使用我的 100% 工作方法。这是例子-
$this_device_session = \Session::getId(); //user's current session id is stored
//check in sessions table. If record exist then delete it skipping the current session.
if(DB::table('sessions')->where('id','!=',$this_device_session)->where('user_id',Auth::user()->id)->exists()) {
//delete their session
DB::table('sessions')->where('id','!=',$this_device_session)->where('user_id',Auth::user()->id)->delete();
}
return view('dashboard'); //user's dashboard page or any page you want