Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

marcellopato's avatar

Auth:sanctum How o prevent user to login more than once on other devices at the same time?

Hello everybody! I have a brand new Laravel 10 with Jetstream, Sanctum, Fortify app and I want to allow users to login only once per session. I am not very close to this feature, so if someone could teach me like I was a noob, would appreciate!

0 likes
7 replies
LaryAI's avatar
Level 58

To prevent users from logging in on multiple devices at the same time using Laravel Sanctum, you can follow these steps:

  1. Track Active Sessions: You need to keep track of active sessions for each user. You can do this by storing a token or session identifier in your database whenever a user logs in.

  2. Check for Active Sessions: Before allowing a user to log in, check if there is an active session for that user. If there is, you can either prevent the new login or invalidate the old session.

  3. Invalidate Previous Sessions: If you choose to invalidate the old session, you'll need to delete the existing token or mark it as invalid in your database.

Here's a basic example of how you might implement this:

First, you'll need to create a migration to add a field to your users table to store the current session token:

// Create a new migration file
php artisan make:migration add_current_session_token_to_users_table --table=users

// In the migration file, add the following:
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('current_session_token')->nullable();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn('current_session_token');
    });
}

Run the migration:

php artisan migrate

Next, you'll need to override the login behavior to check for an existing session token and invalidate it if necessary. You can do this in the attemptLogin method in your LoginController:

use Illuminate\Support\Facades\Auth;
use Laravel\Sanctum\PersonalAccessToken;

class LoginController extends Controller
{
    protected function attemptLogin(Request $request)
    {
        // Attempt to log the user in
        if (Auth::attempt($request->only('email', 'password'))) {
            $user = Auth::user();

            // Check if there is an existing session token
            if ($user->current_session_token) {
                // Revoke the existing token
                PersonalAccessToken::findToken($user->current_session_token)->delete();
            }

            // Create a new token for the current session
            $token = $user->createToken('session-token')->plainTextToken;

            // Store the new session token
            $user->current_session_token = explode('|', $token, 2)[1];
            $user->save();

            return true;
        }

        return false;
    }
}

This is a simplified example and may need to be adjusted based on your specific application setup. You'll also need to ensure that when a user logs out, the current_session_token is cleared from the user's record.

Remember to handle token revocation properly in your logout method:

public function logout(Request $request)
{
    $user = Auth::user();

    // Revoke the user's current token
    if ($user->current_session_token) {
        PersonalAccessToken::findToken($user->current_session_token)->delete();
        $user->current_session_token = null;
        $user->save();
    }

    // Perform other logout operations like `Auth::logout()`
}

This approach ensures that a user can only have one active session at a time. If they log in from another device, the previous session will be invalidated.

marcellopato's avatar

But there is no LoginController at this moment. Should I just create it, and it will take care of the actual login method?

Snapey's avatar

No need for this complicated treatment. By default the login page is protected by redirectIfAuthenticated middleware. This sends an authenticated user away from the login route so that they cannot reach a login form.

1 like
marcellopato's avatar

@Snapey

    Route::get('/dashboard', function () {
        return view('dashboard');
    })->name('dashboard');

    // Superadministrators
    Route::group(['prefix' => '/admin'], function () {
        Route::resource('users', Super\UsersController::class);
        Route::resource('permissions', Super\PermissionController::class);
        Route::resource('roles', Super\RoleController::class);
    });

});

There is no LoginController since I am using Jetstream, 'cause it handles all of it, I guess. I read the Laravel doc's, but couldn't get where to put stuff... can I ask You to write some code for me, please? Or maybe say what and where should I do?
Thanks
Snapey's avatar

When you say only login once, you are talking about on the same device?

marcellopato's avatar

@Snapey I am talking about user are not allow sharing credentials, so some else uses his profile at the same time on another computer or device. My system is paid by user, and I need guarantee that the user do not share his credentials. Sorry if I did not make myself clear, @snapey

dvillecco's avatar

We are using Sanctum. User logs in the web app and then in our mobile app, then web token gets expired. Same thing viceversa. What should we do? Thanks in advance. @snapey

Please or to participate in this conversation.