skip to Main Content

I am developing a Laravel application and need to implement a security feature that allows users to log in from only one device at a time. In other words, I want to enforce a single session per user in my application.

I understand that Laravel provides built-in session management functionality but doesn’t inherently restrict users from logging in from multiple devices simultaneously. To achieve this requirement, I seek guidance on implementing a solution that ensures a user can only have one active session at a time.

Here are some specific questions I have:

  1. How can I detect and prevent multiple logins from the same user
    account?
  2. What is the best approach to invalidate previous sessions when a user logs in from a new device?
  3. How can I handle cases where a user’s session becomes inactive or expires?

I would greatly appreciate any insights or code examples to help me accomplish this task.

This is my current Login method:

public function store(LoginRequest $request)
{
    $request->authenticate();

    // Check if the user already has an active session
    $previousSessionId = Redis::get('ga:user_session_id:' . Auth::id());

    if ($previousSessionId) {
        // Destroy the previous session
        Redis::del('ga:user_session_id:' . Auth::id());

        // Logout the user
        Auth::logout();

        return abort(403); // Return an error response indicating that multiple sessions are not allowed
    }

    $request->session()->regenerate();

    $user = Auth::user();
    $sessionId = uniqid(); // Generate a unique session ID

    // Store the unique session ID in Redis
    Redis::set('ga:user_session_id:' . $user->id, $sessionId);

    if (Auth::user()) {
        if (Auth::user()->hasRole('الوصول الى لوحة التحكم')) {
            return redirect()->route('dashboard');
        } else {
            return redirect()->intended(RouteServiceProvider::HOME);
        }
    }
}

Using the previous code, for example, if I logged in using device 1, it logged in successfully. If I logged in using device 2 while device 1 was logged in, it returned 403, but when I refreshed the tab, it logged device 2 as well, and both devices were logged in simultaneously.

2

Answers


  1. You can use the built-in session management functionality in Laravel to enforce a single session per user. When a user logs in, you can store their session ID in the database or cache. Then, when the same user logs in from another device, you can invalidate their previous session.

    public function store(LoginRequest $request)
    {
        $request->authenticate();
    
        $user = Auth::user();
    
        // Get the previous session ID from the cache
        $previousSessionId = Redis::get('user_session_id:' . $user->id);
    
        if ($previousSessionId) {
            // Delete the previous session data
            session()->getHandler()->destroy($previousSessionId);
        }
    
        // Store the current session ID in the cache
        Redis::set('user_session_id:' . $user->id, session()->getId());
    
        $request->session()->regenerate();
    
        if ($user->hasRole('الوصول الى لوحة التحكم')) {
            return redirect()->route('dashboard');
        } else {
            return redirect()->intended(RouteServiceProvider::HOME);
        }
    }
    
    Login or Signup to reply.
  2. You can implement a middleware and apply it to routes that need to be protected and enforced for single-session-per-user.

    <?php
    
    namespace AppHttpMiddleware;
    
    use Closure;
    use IlluminateSupportFacadesAuth;
    
    class SingleSessionMiddleware
    {
        public function handle($request, Closure $next)
        {
            $user = Auth::user();
    
            if ($user && $user->session_token !== session('session_token')) {
                Auth::logout();
                return redirect()->route('login')->with('error', 'You have been logged out from other device.');
            }
    
            return $next($request);
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search