allyans3/laravel-auth-tracker

在 Laravel 中跟踪和管理会话、Passport 令牌和 Sanctum 令牌。

v1.0.1 2023-07-21 13:43 UTC

This package is auto-updated.

Last update: 2024-09-21 16:00:29 UTC


README

在 Laravel 中跟踪和管理会话、Passport 令牌和 Sanctum 令牌。

此包允许您分别跟踪每个登录(会话或令牌),通过解析 User-Agent 并保存 IP 地址附加信息。

使用支持的提供者或创建自己的自定义提供者,您可以通过 IP 地址查找收集更多信息,例如获取地理位置。

您可以撤销每个会话/令牌或一次性撤销所有。对于具有记住令牌的会话,每个会话都有自己的记住令牌。这样,您可以在不影响其他会话的情况下撤销会话。

兼容性

  • 目前,此包与 Laravel 8 不兼容。我正在开发 v3 以支持 Laravel 8。同时,如果您的项目仅基于 Laravel Sanctum 身份验证,您可以安装 Laravel Sanctum Tracker

  • 对于 Laravel 的先前版本(v5.8、v6 和 v7),使用 v2

  • 它支持 Laravel 所支持的所有会话驱动程序,当然,除了当然的 cookie 驱动程序,它仅在客户端浏览器中保存会话,以及数组驱动程序。

  • 为了跟踪 API 令牌,它支持官方的 Laravel Passport (>= 7.5)Laravel Sanctum (v2) 包。

安装

/!\ 本文档适用于 v3(工作进展中)。最新版本(v2)的文档可在此处找到:https://github.com/alajusticia/laravel-auth-tracker/tree/v2

使用 composer 安装包

composer require alajusticia/laravel-auth-tracker

使用以下命令发布配置文件(config/auth_tracker.php)

php artisan vendor:publish --provider="ALajusticia\AuthTracker\AuthTrackerServiceProvider" --tag="config"

创建登录表

在运行迁移之前,您可以使用配置文件中的 table_name 选项更改用于保存登录的表名(默认为 logins)。

启动数据库迁移以创建所需的表

php artisan migrate

准备您的可认证模型

为了跟踪您的应用程序用户的登录,请将 ALajusticia\AuthTracker\Traits\AuthTracking 特性添加到您想要跟踪的每个可认证模型上

use ALajusticia\AuthTracker\Traits\AuthTracking;
use Illuminate\Foundation\Auth\User as Authenticatable;
// ...

class User extends Authenticatable
{
    use AuthTracking;

    // ...
}

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

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

目前,它支持两种最流行的解析器

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

配置用户提供者(可选)

如果您的应用程序只有无状态身份验证,此步骤是可选的。

如果您想使用 Auth Tracker 进行状态认证,此包包含一个修改过的 Eloquent 用户提供者,它从登录表而不是用户表中检索记住的用户。

在您的 config/auth.php 配置文件中,在用户提供者列表中使用 eloquent-tracked 驱动来跟踪您想要跟踪的用户

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

Laravel Sanctum

在 Laravel Sanctum 包的实际版本(2.9)中,没有事件允许我们知道 API 令牌何时创建。

如果您使用 Laravel Sanctum 发放 API 令牌并想启用身份验证跟踪,您将必须分发 Auth Tracker 提供的事件。

分发 ALajusticia\AuthTracker\Events\PersonalAccessTokenCreated 事件,传递由 Laravel Sanctum 特性中的 createToken 方法新创建的个人访问令牌。

根据 Laravel Sanctum 文档提供的示例,可能看起来像这样

use ALajusticia\AuthTracker\Events\PersonalAccessTokenCreated;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

Route::post('/sanctum/token', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
        'device_name' => 'required',
    ]);

    $user = User::where('email', $request->email)->first();

    if (! $user || ! Hash::check($request->password, $user->password)) {
        throw ValidationException::withMessages([
            'email' => ['The provided credentials are incorrect.'],
        ]);
    }

    $personalAccessToken = $user->createToken($request->device_name);
    
    event(new PersonalAccessTokenCreated($personalAccessToken)); // Dispatch here the event

    return $personalAccessToken->plainTextToken;
});

使用方法

此包提供的 AuthTracking 特性为您用户模型增加了列出登录和完全控制它们的方法。

检索登录信息

获取所有登录

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

获取当前登录

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

检查当前登录

每个登录实例都有一个动态的 is_current 属性。它是一个布尔值,表示登录实例是否是当前登录。

撤销登录

撤销特定登录

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

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

撤销所有登录

我们可以使用 logoutAll 方法销毁所有会话并吊销所有 Passport/Sanctum 令牌。这在例如,用户的密码更改并且我们想要注销所有设备时很有用。

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

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

撤销所有登录(除当前登录外)

logoutOthers 方法的行为与 logoutAll 方法相同,只不过它保持当前会话或 Passport/Sanctum 令牌活跃。

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

事件

登录

在新的登录中,您可以监听事件 ALajusticia\AuthTracker\Events\Login。它接收一个包含请求收集的所有信息的 RequestContext 对象,您可以通过事件上的 context 属性访问它。

可用的属性

$this->context->userAgent; // The full, unparsed, User-Agent header
$this->context->ip; // The IP address

可用的方法

$this->context->parser(); // Returns the parser used to parse the User-Agent header
$this->context->ip(); // Returns the IP address lookup provider

解析器中的方法

$this->context->parser()->getDevice(); // The name of the device (MacBook...)
$this->context->parser()->getDeviceType(); // The type of the device (desktop, mobile, tablet, phone...)
$this->context->parser()->getPlatform(); // The name of the platform (macOS...)
$this->context->parser()->getBrowser(); // The name of the browser (Chrome...)

IP 地址查找提供者中的方法

$this->context->ip()->getCountry(); // The name of the country
$this->context->ip()->getRegion(); // The name of the region
$this->context->ip()->getCity(); // The name of the city
$this->context->ip()->getResult(); // The entire result of the API call as a Laravel collection

// And all your custom methods in the case of a custom provider

IP 地址查找

默认情况下,Auth Tracker 收集 IP 地址和 User-Agent 标头提供的信息。

但您可以去得更远,收集有关 IP 地址的其他信息,例如地理位置。

要这样做,您首先必须在配置文件中启用 IP 查找功能。

此包包含两个官方支持的 IP 地址查找提供者(请参阅 config/auth_tracker.php 配置文件中的 IP 地址查找部分)。

Ip2Location Lite DB3

此包官方支持使用 Ip2Location Lite DB3 的 IP 地址地理位置。

以下是启用和使用它的步骤

  • 下载当前版本的数据库,并根据文档中的说明将其导入您的数据库:https://lite.ip2location.com/database/ip-country-region-city

  • config/auth_tracker.php 配置文件中将 ip_lookup.provider 选项的名称设置为 ip2location-lite

  • config/auth_tracker.php 配置文件中指示您的数据库中用于 IPv4 和 IPv6 的表名(默认情况下,它使用与文档相同的名称:ip2location_db3ip2location_db3_ipv6

自定义提供者

您可以通过创建一个实现 ALajusticia\AuthTracker\Interfaces\IpProvider 接口并使用 ALajusticia\AuthTracker\Traits\MakesApiCalls 特性的类来添加自己的提供者。

您的自定义类必须注册到配置文件的 custom_providers 数组中。

让我们看看一个使用内置的 IpApi 提供者的 IP 查找提供者的示例

use ALajusticia\AuthTracker\Interfaces\IpProvider;
use ALajusticia\AuthTracker\Traits\MakesApiCalls;
use GuzzleHttp\Psr7\Request as GuzzleRequest;
use Illuminate\Support\Facades\Request;

class IpApi implements IpProvider
{
    use MakesApiCalls;

    /**
     * Get the Guzzle request.
     *
     * @return GuzzleRequest
     */
    public function getRequest()
    {
        return new GuzzleRequest('GET', 'http://ip-api.com/json/' . Request::ip() . '?fields=25');
    }

    /**
     * Get the country name.
     *
     * @return string
     */
    public function getCountry()
    {
        return $this->result->get('country');
    }

    /**
     * Get the region name.
     *
     * @return string
     */
    public function getRegion()
    {
        return $this->result->get('regionName');
    }

    /**
     * Get the city name.
     *
     * @return string
     */
    public function getCity()
    {
        return $this->result->get('city');
    }
}

如你所见,这个类有一个必须返回一个 GuzzleHttp\Psr7\Request 实例的 getRequest 方法。

Guzzle 使用 PSR-7 作为 HTTP 消息接口。查看其文档:[http://docs.guzzlephp.org/en/stable/psr7.html](http://docs.guzzlephp.org/en/stable/psr7.html)

IpProvider 接口包含与地理位置相关的必需方法。API 响应的所有键都可以通过你的提供者在 $this->result 中访问,它是一个 Laravel 集合。

如果你想收集其他信息,你可以在你的自定义提供器中添加一个 getCustomData 方法。这些自定义数据将被保存到 ip_data JSON 列表中,在登录表的 ip_data 中。让我们看一个附加数据的示例

public function getCustomData()
{
    return [
        'country_code' => $this->result->get('countryCode'),
        'latitude' => $this->result->get('lat'),
        'longitude' => $this->result->get('lon'),
        'timezone' => $this->result->get('timezone'),
        'isp_name' => $this->result->get('isp'),
    ];
}

处理 API 错误

如果在你的 IP 地址查找提供器的 API 调用期间抛出异常,这个包会触发 FailedApiCall 事件。

此事件具有一个包含 GuzzleHttp\Exception\TransferException 的异常属性(见 Guzzle 文档)。

你可以监听此事件以添加自己的逻辑。

Blade 指令

检查当前用户是否启用了身份验证跟踪

@tracked
    <a href="{{ route('login.list') }}">Security</a>
@endtracked

检查 IP 查找功能是否已启用

@ipLookup
    {{ $login->location }}
@endipLookup

许可证

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