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