• Время чтения ~1 мин
  • 03.07.2023

Недавно у меня украли мобильный телефон, и я понял, сколько приложений не имеют функции управления сеансом. Я не мог выйти из этого устройства.

К счастью, Laravel предоставляет способ аннулировать и «выйти» из системы сеансы активного пользователя на других устройствах, не аннулируя сеанс на его текущем устройстве.

Ниже я перечислю несколько случаев, когда эта функция может быть полезна:

  • Пользователь потерял или украл свое устройство.
  • Пользователь меняет свой пароль.
  • Приложение не должно допускать несколько сеансов одновременно.

Аннулирование сеансов на других устройствах Чтобы аннулировать сессию пользователя на всех устройствах

, кроме текущего, необходимо вызвать метод.Auth::logoutOtherDevices Это требует, чтобы пользователи подтвердили пароль.

Это важно, потому что, если пользователь потерял или у него украли мобильный телефон, вы не можете позволить кому-либо выйти из всех сеансов с помощью этого устройства.

use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($currentPassword);

Чтобы logoutOtherDevices метод работал, Laravel предоставляет Illuminate\Session\Middleware\AuthenticateSessionпромежуточное программное обеспечение, которое обнаруживает изменения хэша пароля, немедленно выходит из системы пользователя и запускает Illuminate\Auth\Events\CurrentDeviceLogout событие.

По умолчанию ПО промежуточного слоя может быть присоединено к маршруту с помощью псевдонима auth.session ПО промежуточного слоя маршрута, AuthenticateSession как определено в HTTP-ядре приложения
Официальная документация Laravel

routes/web.php

Route::middleware(['auth', 'auth.session'])->group(function () {
    Route::get('/', function () {
        // ...
    });
});

Тогда вы, возможно, уже думаете о том, что он logoutOtherDevices делает. Он перефразирует пароль. Хм, но меняется ли хэш даже при использовании одного и того же пароля? Да, это так!

Объяснение Laravel Hash::make()

Аннулирование сеанса определенного устройства

Это возможно, но необходимо управлять сеансами с помощью драйвера базы данных. Это позволяет запрашивать сеансы и отображать список для пользователя, чтобы выбрать конкретный сеанс для аннулирования.

Драйверу базы данных требуется таблица. Вы можете использовать session:table команду artisan для создания этой миграции.

php artisan session:table
php artisan migrate

Установите драйвер в config/session.php файле как базу данных:Или через SESSION_DRIVER атрибут в файле env:Затем создайте модель для таблицы сеансов:Создайте связи:Теперь вы можете перечислить сессии:Пример того, как это должно выглядеть:

//...
'driver' => env('SESSION_DRIVER', 'database')
//...

SESSION_DRIVER=database

php artisan make:model Session

namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Session extends Model
{
    public $incrementing = false;
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

namespace App\Models;
//...
use Illuminate\Database\Eloquent\Relations\HasMany;
class User extends Authenticatable
{
    //...
    public function sessions(): HasMany
    {
        return $this->hasMany(Session::class);
    }
}

config/session.php

$user = auth()->user();
$sessions = $user->sessions()
    ->select('id', 'ip_address', 'user_agent', 'last_activity')
    ->get();
dump($sessions->toArray());

env

array:3 [▼ // routes/web.php:18
  0 => array:4 [▶
    "id" => "J9KBJgsqKWRu4JGhNpTF73EBhGXD9FneIR2vzEqX"
    "ip_address" => "217.240.75.140"
    "user_agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ..."
    "last_activity" => 1688043153
  ]
  1 => array:4 [▶
    "id" => "mfmRbbeR803hPpi0uLlPYtWaahqgw6CglEu5UMv7"
    "ip_address" => "21.51.178.175"
    "user_agent" => "Mozilla/5.0 (iPhone; CPU iPhone OS 11_6_9; like Mac OS X) ..."
    "last_activity" => 1688043136
  ]
  2 => array:4 [▶
    "id" => "VCkIFZN0zjKq808gvps7haz8XzOkOjnxVlZQifwe"
    "ip_address" => "25.31.180.18"
    "user_agent" => "Mozilla / 5.0 (compatible; MSIE 8.0; Windows; U; Windows NT 10.0; WOW64; en-US Trident / 4.0)"
    "last_activity" => 1688043145
  ]
]

Наконец, чтобы уничтожить конкретную сессию, вам нужно удалить ее из базы данных. В приведенном ниже примере мы отключаем iPhone:

$user->sessions()
    ->where('id', 'mfmRbbeR803hPpi0uLlPYtWaahqgw6CglEu5UMv7')
    ->delete();

В заключение

В этом посте вы узнали о важности управления сеансом для каждого устройства и о том, как этого можно добиться с помощью Laravel.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297