Нещодавно у мене вкрали мобільний телефон і я зрозумів, скільки програм не мають функції контролю сеансу. Не вдалося вийти з цього пристрою.
На щастя, Laravel надає спосіб зробити сеанси активного користувача недійсними та "вийти" з них на інших пристроях, не визнаючи сеанс недійсним на їх поточному пристрої.
Нижче я перераховую кілька випадків, коли ця функція може бути корисною:
- Користувач втрачає або його пристрій викрадено.
- Користувач змінює свій пароль.
- Додаток не повинен дозволяти кілька сеансів одночасно.
Визнання сеансів недійсними на інших пристроях Щоб зробити сеанс користувача недійсним на всіх пристроях
, крім поточного, потрібно викликати метод.Auth::logoutOtherDevices
Він вимагає від користувачів підтвердження пароля.
Це важливо, оскільки, якщо користувач загубив або у нього вкрали мобільний телефон, ви не можете дозволити комусь вийти з усіх сеансів за допомогою цього пристрою.
use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($currentPassword);
Для роботи методу Laravel надає Illuminate\Session\Middleware\AuthenticateSession
проміжне програмне забезпечення, яке виявляє зміни хешу logoutOtherDevices
пароля, негайно виходить із системи користувача та запускає Illuminate\Auth\Events\CurrentDeviceLogout
подію.
За замовчуванням проміжне
AuthenticateSession
програмне забезпечення може бути приєднане до маршруту, використовуючиauth.session
псевдонім проміжного програмного забезпечення маршруту, як визначено в HTTP-ядрі вашої програми
Офіційна документація
routes/web.php
Route::middleware(['auth', 'auth.session'])->group(function () {
Route::get('/', function () {
// ...
});
});
LaravelТоді ви, можливо, вже думаєте про те, що робитьlogoutOtherDevices
. Він повторно перевіряє пароль. Так, але чи змінюється хеш навіть при використанні одного і того ж пароля? Так, це так!
Визнання недійсним сеансу певного пристрою
Це можливо, але ви повинні керувати сеансами за допомогою драйвера бази даних. Це дозволяє запитувати сеанси та відображати список користувачеві для вибору конкретного сеансу для визнання недійсним.
Драйверу бази даних потрібна таблиця. Ви можете використовувати команду ремісника session:table
для створення цієї міграції.
php artisan session:table
php artisan migrate
Встановіть драйвер у файлі як базу даних:Або через атрибут у файлі config/session.php
env:Потім створіть модель для таблиці сеансу:Створіть зв'язки:Тепер ви можете перерахувати сеанси:Приклад того, як це має виглядати:
//...
'driver' => env('SESSION_DRIVER', 'database')
//...
SESSION_DRIVER=database
php artisan make:model Session
config/session.php
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);
}
}
$user = auth()->user();
$sessions = $user->sessions()
->select('id', 'ip_address', 'user_agent', 'last_activity')
->get();
dump($sessions->toArray());
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
]
]
Нарешті, щоб знищити певний сеанс, потрібно видалити його з бази даних.SESSION_DRIVER
У наведеному нижче прикладі ми відключаємо iPhone:
$user->sessions()
->where('id', 'mfmRbbeR803hPpi0uLlPYtWaahqgw6CglEu5UMv7')
->delete();
На завершення
У цій публікації ви дізналися про важливість контролю сеансу на пристрої та про те, як цього можна досягти за допомогою Laravel.