To prevent users from logging in on multiple devices at the same time using Laravel Sanctum, you can follow these steps:
-
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.
-
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.
-
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.