drewlabs/laravel-http-guard
Laravel/Lumen 使用 HTTP 协议接口的认证保护器
Requires
- php: ^7.2|^8.0
- drewlabs/contracts: ^0.3
- drewlabs/core-helpers: ^0.3
- drewlabs/curl-rest-client: ^0.2.0|^0.3.0|^0.4.0
- illuminate/support: ^9.0|^10.0|^11.0
Requires (Dev)
- phpunit/phpunit: ^9.5
Suggests
- drewlabs/net: Required to ping available servers ^0.1.0
- ext/memcached: Required to use the memcached provider.
- predis/predis: Required to use the redis cache provider.
README
使用 OAuth bearer 令牌通过远程服务器进行身份验证的 HTTP 保护器实现。
注意:由于 API 可能会频繁更改,该软件包处于积极开发中,请参阅更改日志和 README 以了解任何更改。
使用方法
- 服务提供者
默认情况下,库通过 composer 的 extras 标志构建以注入 laravel 项目的服务提供者。对于 lumen 应用程序,必须手动注册服务提供者类。
// app/bootrap.php // ... /* |-------------------------------------------------------------------------- | Register Service Providers |-------------------------------------------------------------------------- | | Here we will register all of the application's service providers which | are used to bind services into the container. Service providers are | totally optional, so you are not required to uncomment this line. | */ $app->register(\Drewlabs\HttpGuard\ServiceProvider::class);
- 配置 Laravel/Lumen 项目的保护器
如果上一节成功完成,http-guard 库将尝试从 auth.php
配置文件加载基本配置。如果缺失,请添加 config/auth.php
,并包含以下内容
return [ // Default values in the auth configuration file // ... 'guards' => [ // You add other guard drivers // ... // Configuration of the http guard driver 'http' => [ 'driver' => 'http' ], ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ // Here in the providers key of the array, we define the basic configuration that will be loaded by the library service provider at runtime as follow: 'providers' => [ // ... 'http' => [ // Model class to be used by the package providers 'model' => \Drewlabs\HttpGuard\User::class, // For Http request we must define the endpoint where is located the // authorization server(s) 'hosts' => [ // When not using a cluster of servers, this default host is used 'default' => 'https://:4300', // Cluster of servers to be used for authentication 'cluster' => [ [ 'host' => '<HOST_URL>', 'primary' => true, // Boolean value indicating whether the host should be query first as primary node ] ] ] ] ], // ... ];
注意:在上面的配置文件中,我们定义了软件包在 Laravel 项目中正常运行所需的基本配置。
- 定义 http 保护器作为默认保护器
如果在具有多个保护提供者的环境中运行,如 Laravel 框架中,开发者应记住在 auth.php
配置文件中将 http 保护器添加为默认保护器。
// auth.php // ... return [ // .. /* |-------------------------------------------------------------------------- | Authentication Defaults |-------------------------------------------------------------------------- | | This option controls the default authentication "guard" and password | reset options for your application. You may change these defaults | as required, but they're a perfect start for most applications. | */ 'defaults' => [ 'guard' => 'http', ], // ... ];
- 添加保护中间件
Laravel 随附一个安全中间件,可以保护路由免受未经授权用户的侵害。由于 Laravel 设置使用保护器,并且 http-guard 是为了支持 Laravel 安全系统而构建的,因此如果正确完成上述配置,开发者可以使用 Laravel 应用程序中随附的默认中间件。
但对于那些想要创建自己的中间件的人来说,这里有一个示例实现
// app/Http/Middleware.php namespace App\Http\Middleware; use Closure; use Illuminate\Auth\AuthenticationException; use Illuminate\Http\Request; use Illuminate\Contracts\Auth\Factory as Auth; class Authenticate { /** * @var Factory */ protected $auth; /** * Create a new BaseMiddleware instance. * * @param Auth $auth */ public function __construct(Auth $auth) { $this->auth = $auth; } /** * Handle an incoming request. * * @param Request $request * @param \Closure $next * @param string[] ...$guards * @return mixed * */ public function handle($request, Closure $next, ...$guards) { $this->authenticate($guards); return $next($request); } /** * Determine if the user is ged in to any of the given guards. * * @param array $guards * @return void * * @throws AuthenticationException */ protected function authenticate(array $guards) { if (empty($guards)) { $guards = [null]; } // To authenticate users, loop through all the guards provided as parameter // to the middleware and check if users are authenticated foreach ($guards as $guard) { if ($this->auth->guard($guard)->check()) { return $this->auth->shouldUse($guard); } } $this->unauthenticated($guards); } /** * Handle an unauthenticated user. * * @param array $guards * @return void * * @throws AuthenticationException */ protected function unauthenticated(array $guards) { throw new AuthenticationException('Unauthenticated.', $guards); } }
- 注册中间件
对于 Laravel 应用程序,中间件必须在 app/Http/Kernel.php
文件中注册,如下所示
// app/Http/Kernel.php class Kernel extends HttpKernel { /** * The application's route middleware. * * These middleware may be assigned to groups or used individually. * * @var array */ protected $routeMiddleware = [ // ... 'auth' => \App\Http\Middleware\Authenticate::class, ]; // ... }
对于 Lumen 应用程序
// app/bootstrap.php // ... /* |-------------------------------------------------------------------------- | Register Middleware |-------------------------------------------------------------------------- | | Next, we will register the middleware with the application. These can | be global middleware that run before and after each request into a | route or middleware that'll be assigned to some specific routes. | */ $app = $app->routeMiddleware([ // ... 'auth' => \App\Http\Middleware\Authenticate::class, ]);
- 缓存
缓存是每个应用程序的重要方面,因此 http-guard 提供了一种机制,即使身份验证或授权服务器关闭,也可以验证用户令牌。
当授权服务器关闭时,http-guard 库将尝试从该缓存提供者加载用户,并验证令牌的发行日期是否仍然有效。如果令牌的发行日期仍然有效,则用户被认为是授权访问应用程序资源的,否则保护器将用户标记为未经授权。
因此,http-guard 库提供了各种缓存系统,使用数组存储(具有文件转储器的内存中存储)、memcached 服务器存储和 Redis 存储。当运行 laravel
或 lumen
应用程序时,从 config/database.php
加载 memcached 服务器的配置。否则,必须手动定义配置。
注意:库使用静态类属性用于配置值,因此在手动定义配置值时,请记住将操作集中化,以便在每个请求中运行一次。
以下示例定义用于 AuthServiceProvider
类的配置值,适用于 laravel
/ lumen
应用程序
// app/Providers/AuthServiceProvider.php class AuthServiceProvider extends ServiceProvider { // ... /** * Boot the authentication services for the application. * * @return void */ public function boot() { // Configure the Http-Guard library to use cache \Drewlabs\HttpGuard\HttpGuardGlobals::usesCache(true); // Configure the http-guard library to use PHP 'memcached' storage as default driver \Drewlabs\HttpGuard\HttpGuardGlobals::useCacheDriver('memcached'); // ... } }
使用 Redis 作为缓存驱动器
如前所述,库提供了一个依赖 predis/predis
库的 Redis 存储提供者。为了使用 Redis 存储提供者,开发者必须手动安装 predis/predis
。如果在 composer 环境中运行(推荐),可以按以下方式安装库
composer require predis/predis
接下来您需要按照以下步骤配置库以使用redis作为缓存提供者
// Configure the Http-Guard library to use cache \Drewlabs\HttpGuard\HttpGuardGlobals::usesCache(true); // Configure the http-guard library to use redis storage as default driver \Drewlabs\HttpGuard\HttpGuardGlobals::useCacheDriver('redis'); // Define the redis connection configuration as defined in predis documentation \Drewlabs\HttpGuard\HttpGuardGlobals::forRedis([ 'scheme' => 'tcp', 'host' => '10.0.0.1', 'port' => 6379, ]); // ...
注意:Predis文档可以在以下链接找到 [https://github.com/predis/predis]
- 认证服务器集群
如果您的平台配置支持多个服务器进行认证,请在config/auth.php[providers[http][hosts][cluster]]
映射条目中声明集群列表。
注意:在运行集群时,开发者必须提供一个后台任务,定期调用[\Drewlabs\HttpGuard\AuthServerNodesChecker::setAvailableNode()]来更新集群中的可用节点。
- 自定义
-- 身份认证Web服务路由
默认情况下,保护实现期望身份认证Web服务提供api/v2/user
和api/v2/logout
作为路由来解析连接用户和撤销认证令牌。但开发者可以通过以下方式自定义此行为
// app/AuthServiceProvider.php use Drewlabs\HttpGuard\HttpGuardGlobals; class AuthServiceProvider extends ServiceProvider { // ... public function boot() { // ... HttpGuardGlobals::userPath('auth/v2/user'); // Set the api prefix to equal auth instead of api HttpGuardGlobals::revokePath('auth/v2/logout'); } }
-- 保护名称
默认情况下,库假定配置的保护名称是http
。根据应用约束,开发者可能决定全局自定义保护名称。要更改默认行为
// app/AuthServiceProvider.php use Drewlabs\HttpGuard\HttpGuardGlobals; class AuthServiceProvider extends ServiceProvider { // ... public function boot() { // ... HttpGuardGlobals::guard('api'); // Defines the guard name to be used by the library as `api` } }
-- 用户工厂
从请求响应中构建用户实例并验证所需输入可能是一项繁琐的任务。因此,库提供了一个默认的用户工厂类,该类从请求响应体中构建Drewlabs\Contracts\Auth\Authenticatable::class
和\Illuminate\Contracts\Auth\Authenticatable::class
的实例。但默认工厂类可以被覆盖,方法是将\Drewlabs\HttpGuard\Contracts\UserFactory
绑定到容器中,或通过全局定义用户工厂类。
// app/AuthServiceProvider.php use Drewlabs\HttpGuard\Contracts\UserFactory; class AuthServiceProvider extends ServiceProvider { // ... public function register() { // ... // Defining the user factory $this->app->bind(UserFactory::class, function() { return function(array $attributes = [], ?string $token = null) { // Creates the instance of Authenticatable class return $user; }; }); } }
或在auth.php
return [ // Default values in the auth configuration file // ... 'guards' => [ // You add other guard drivers // ... // Configuration of the http guard driver 'http' => [ 'driver' => 'http' ], ], // .... 'providers' => [ // ... 'http' => [ // ... // Using a class : Uncomment the code below to use the class // 'userFactory' => \App\UserFactory::class, // Using a closure 'userFactory' => function(array $attributes = [], ?string $token = null) { } ] ], ];