Недавно у меня украли мобильный телефон, и я понял, сколько приложений не имеют функции управления сеансом. Я не мог выйти из этого устройства.
К счастью, 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
делает. Он перефразирует пароль. Хм, но меняется ли хэш даже при использовании одного и того же пароля? Да, это так!
Аннулирование сеанса определенного устройства
Это возможно, но необходимо управлять сеансами с помощью драйвера базы данных. Это позволяет запрашивать сеансы и отображать список для пользователя, чтобы выбрать конкретный сеанс для аннулирования.
Драйверу базы данных требуется таблица. Вы можете использовать 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.