alajusticia/laravel-logins

Laravel 应用中的会话和Sanctum令牌跟踪,用户在登录时收到通知,多个记住的令牌,IP地理位置,User-Agent解析器

资助包维护!
Ko Fi

v1.2.3 2024-09-10 20:33 UTC

This package is auto-updated.

Last update: 2024-09-10 20:37:36 UTC


README

  • 跟踪每次登录,附加设备信息(设备类型、设备名称、操作系统、浏览器、IP地址)和上下文(日期、位置)
  • 将这些信息保存到您的数据库中,以便您可以在用户的账户中显示它
  • 通知用户新的登录,以及收集到的信息
  • 允许您的用户注销特定设备、除了当前设备外的所有设备,或一次性注销所有设备
  • 注销设备,不影响其他记住的设备(每个记住的会话都有自己的令牌)
  • 您还可以启用Sanctum个人访问令牌的跟踪,例如在验证移动应用时很有用

Screenshot of the notification sent on a new login

兼容性

  • 此包已在Laravel 10和11上进行了测试

  • 它与Laravel支持的所有会话驱动程序兼容,但cookie驱动程序仅将会话保存在客户端浏览器中,以及数组驱动程序不兼容

  • 它还支持由Laravel Sanctum (v3)提供的个人访问令牌

安装

使用Composer安装包

composer require alajusticia/laravel-logins

使用以下命令发布配置文件(logins.php):

php artisan vendor:publish --tag="logins-config"

运行 logins:install 命令(这将运行所需的数据库迁移)

php artisan logins:install

准备可验证的模型

为了跟踪您应用程序用户的登录,将 ALajusticia\Logins\Traits\HasLogins 特性添加到您想要跟踪的可验证模型中

use ALajusticia\Logins\Traits\HasLogins;
use Illuminate\Foundation\Auth\User as Authenticatable;
// ...

class User extends Authenticatable
{
    use HasLogins;

    // ...
}

选择并安装一个用户代理解析器

此包依赖于用户代理解析器来提取信息。

它支持两种最受欢迎的解析器

在开始使用Laravel Logins之前,您需要选择一个支持的解析器,安装它,并在配置文件中指定您想要使用哪一个。

配置认证守卫

此包附带一个自定义认证守卫(ALajusticia\Logins\LoginsSessionGuard),它扩展了默认的Laravel会话守卫,在logout()logoutCurrentDevice()logoutOtherDevices()方法中添加了删除相关登录的逻辑。

在您的auth.php配置文件的guards选项中,使用logins驱动程序而不是session驱动程序

'guards' => [
    'web' => [
        'driver' => 'logins',
        'provider' => 'users',
    ],
    
    // ...
],

配置用户提供者

此包附带一个修改后的Eloquent用户提供者,从登录表中检索记住的用户,使每个会话都有自己的记住令牌,并使我们能够单独撤销会话。

当使用Laravel登录时,您无需使用Illuminate\Session\Middleware\AuthenticateSession中间件来使“注销其他设备”功能生效。由于每个登录都有自己的记住我的令牌,我们不必重新散列用户密码或为每次请求添加使用AuthenticateSession中间件检查密码散列的开销。

在您的auth.php配置文件中,对于您想要启用登录的用户,请在用户提供者列表中使用logins驱动程序。

'providers' => [
    'users' => [
        'driver' => 'logins',
        'model' => App\Models\User::class,
    ],
    
    // ...
],

Laravel Sanctum

除了会话之外,Laravel登录还支持跟踪Laravel Sanctum签发的个人访问令牌(有关支持版本的详细信息,请参阅兼容性部分)。

如果您需要从外部应用程序(例如移动应用程序)验证用户,此功能可能很有用。

ℹ️如果您只跟踪有状态 Sanctum 验证(例如与 Inertia.js 一起使用),则无需启用此功能。

要启用它,请在您的logins.php配置文件中将sanctum_token_tracking设置为true。如果您在安装Laravel登录后安装了Laravel Sanctum,您将必须再次运行logins:install命令以更新您的安装。

启用Sanctum跟踪后,每当签发令牌时,都会分派LoggedIn事件。此外,与令牌相关的登录会以与我们管理会话相同的方式列出和管理。这意味着,例如,当调用logoutAll()方法时,将删除所有会话和所有个人访问令牌。如果您具有混合用例,并且还为其他分离的目的(例如API访问)签发Sanctum个人访问令牌,这可能不是您想要的行为。如果是这样,您可以在您的logins.php配置文件中的sanctum_token_name_regex选项中定义一个正则表达式,并且只有名称与定义的模式匹配的令牌将被跟踪为“登录”

'sanctum_token_name_regex' => '/^mobile_app_/',

Laravel Jetstream

如果您使用Laravel Jetstream,您可以停止使用AuthenticateSession中间件,因为登录不需要它。

在您的jetstream.php配置文件中,将auth_session设置为null

'auth_session' => null,

在您的路由中删除中间件。

Route::middleware([
    'auth:sanctum',
-    config('jetstream.auth_session'),
    'verified',
])->group(function () {
    // ...
});

此外,如果您使用带有Livewire堆栈的Jetstream,安装命令将在您的项目中复制一个Livewire组件(如果Jetstream在安装登录后安装,您将必须再次运行logins:install命令以更新您的安装)。

Screenshot of the Livewire component

文件将复制到app/Livewire/Logins.phpresources/views/livewire/logins.blade.php

要使用组件,请将配置文件(resources/views/profile/show.blade.php)中配置文件中配置的LogoutOtherBrowserSessionsForm组件替换为Logins组件。

<div class="mt-10 sm:mt-0">
-    @livewire('profile.logout-other-browser-sessions-form')
+    @livewire('logins')
</div>

请随意修改组件以满足您的需求。

用法

ALajusticia\Logins\Traits\HasLogins特性为您可验证的模型提供检索和管理用户登录的方法。

每次发生新的成功登录或创建Sanctum令牌时,都会自动将有关请求的信息保存到数据库中的logins表中。

此外,如果在logins.php配置文件中定义了通知类,则会向用户发送包含该信息的通知。

检索登录信息

获取所有登录

$logins = request()->user()->logins;

获取当前登录

$currentLogin = request()->user()->current_login;

检查当前登录

每个登录实例都带有一个动态的is_current属性。

它是一个布尔值,表示登录实例是否对应于当前会话或当前使用的个人访问令牌相关的登录。

撤销登录

撤销特定的登录

使用我们的自定义用户提供者,您有权注销特定设备,因为每个会话都有自己的记住我的令牌。

要撤销特定的登录,请使用具有要撤销的登录ID的logout方法。如果没有提供参数,将撤销当前登录。

request()->user()->logout(1); // Revoke the login where id=1
request()->user()->logout(); // Revoke the current login

撤销所有登录

我们可以通过使用logoutAll方法销毁所有会话和撤销所有Sanctum令牌。

此功能会销毁所有会话,包括已记住的会话。

request()->user()->logoutAll();

撤销除了当前登录之外的所有登录

logoutOthers 方法与 logoutAll 方法的作用相同,但会保留当前会话或 Sanctum 令牌。

request()->user()->logoutOthers();

IP地址地理位置

除了从用户代理提取的信息外,您还可以根据客户端的 IP 地址收集有关位置的信息。

要使用此功能,您必须安装和配置此软件包: https://github.com/stevebauman/location。然后,在 logins.php 配置文件中启用 IP 地址地理定位。

默认情况下,这是确定客户端 IP 地址的方式

// Support Cloudflare proxy by checking if HTTP_CF_CONNECTING_IP header exists
// Fallback to built-in Laravel ip() method in Request

return $_SERVER['HTTP_CF_CONNECTING_IP'] ?? request()->ip();

您可以通过向 ALajusticia\Logins\Logins 类的 getIpAddressUsing() 静态方法传递一个闭包来定义自己的 IP 地址解析逻辑,并返回解析后的 IP 地址。

在服务提供商的 boot() 方法中调用它,例如在您的 App\Providers\AppServiceProvider

\ALajusticia\Logins\Logins::getIpAddressUsing(function () {
    return request()->ip();
});

事件

已登录

在新的登录过程中,您可以监听 ALajusticia\Logins\Events\LoggedIn 事件。

它接收认证模型(在 $authenticatable 属性中)和包含有关请求收集的所有信息的 ALajusticia\Logins\RequestContext 对象(在 $context 属性中)。

use ALajusticia\Logins\Events\LoggedIn;
use Illuminate\Support\Facades\Event;

Event::listen(function (LoggedIn $event) {
    
    // Methods available in RequestContext:
    $event->context->date(); // Returns the date of the login (Carbon object)
    $event->context->userAgent(); // Returns the full, unparsed, User-Agent header
    $event->context->ipAddress(); // Returns the client's IP address
    $event->context->parser(); // Returns the parser used to parse the User-Agent header
    $event->context->location(); // Returns the location (Stevebauman\Location\Position object), if IP address geolocation enabled
    $event->context->tokenName(); // Returns the personal access token name (if Sanctum stateless authentication)
    
    // Methods available in the parser:
    $this->context->parser()->getDevice(); // The name of the device
    $this->context->parser()->getDeviceType(); // The type of the device (desktop, mobile, tablet or phone)
    $this->context->parser()->getPlatform(); // The name of the platform/OS
    $this->context->parser()->getBrowser(); // The name of the browser
})

通知

如果您想在用户账户出现新的访问时向他们发送通知,请将通知类传递到 logins.php 配置文件中的 new_login_notification 选项。

Laravel Logins 随附一个可立即使用的通知(ALajusticia\Logins\Notifications\NewLogin),或者您可以使用自己的。

翻译

此软件包包括英文、西班牙文和法文的翻译。

如果您想自定义翻译或添加新的翻译,您可以通过运行此命令来发布语言文件

php artisan vendor:publish --tag="logins-lang"

清除过期的登录

此软件包使用 Laravel Expirable 来使登录模型可过期。

要清除过期的登录,您可以将 ALajusticia\Logins\Models\Login 类添加到 expirable.php 配置文件的 purge 数组中。

    'purge' => [
        \ALajusticia\Logins\Models\Login::class,
    ],

许可

开源,许可协议为 MIT 许可证