mpyw / scoped-auth
为用户身份验证应用特定作用域。
v2.0.2
2023-03-13 06:24 UTC
Requires
- php: ^8.0
- illuminate/auth: ^9.0 || ^10.0 || ^11.0
- illuminate/contracts: ^9.0 || ^10.0 || ^11.0
- illuminate/database: ^9.0 || ^10.0 || ^11.0
- illuminate/support: ^9.0 || ^10.0 || ^11.0
Requires (Dev)
- mockery/mockery: ^1.3.3 || ^1.4.2
- orchestra/testbench: *
- orchestra/testbench-core: >=7.0
- phpunit/phpunit: >=9.5
README
为用户身份验证应用特定作用域。
需求
- PHP:
^8.0
- Laravel:
^9.0 || ^10.0
安装
通过 Composer
$ composer require mpyw/scoped-auth
对于 Fortify 用户
警告
默认的 Fortify 的 RedirectIfTwoFactorAuthenticatable
实现直接使用 UserProvider
下的内部 Model
,然而,Laravel 作者出于某种原因不愿意修复它。因此,我们需要像这样配置 Fortify
CustomFortifyAuthenticator.php
<?php namespace App\Auth; use Illuminate\Http\Request; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\StatefulGuard; use Illuminate\Contracts\Auth\UserProvider; use Laravel\Fortify\Fortify; class CustomFortifyAuthenticator { private const PASSWORD_NAME = 'password'; private readonly UserProvider $provider; public function __construct(StatefulGuard $guard) { // Assert `StatefulGuard` has `getProvider()` which is not declared in the contract assert(method_exists($guard, 'getProvider')); $provider = $guard->getProvider(); assert($provider instanceof UserProvider); $this->provider = $provider; } public function __invoke(Request $request): ?Authenticatable { $user = $this->provider->retrieveByCredentials([ Fortify::username() => $request->input(Fortify::username()), ]); return $user && $this->provider->validateCredentials($user, [ self::PASSWORD_NAME => $request->input(self::PASSWORD_NAME), ]) ? $user : null; } }
AuthServiceProvider.php
<?php namespace App\Providers; use App\Auth\CustomFortifyAuthenticator; use Illuminate\Support\ServiceProvider; use Laravel\Fortify\Fortify; class AuthServiceProvider extends ServiceProvider { public function boot(CustomFortifyAuthenticator $authenticator): void { Fortify::authenticateUsing($authenticator); } }
测试
通过 PHPUnit
$ composer test
用法
在你的 Authenticatable Eloquent 模型上实现 AuthScopable 接口。
<?php namespace App; use Illuminate\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable as UserContract; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Mpyw\ScopedAuth\AuthScopable; class User extends Model implements UserContract, AuthScopable { use Authenticatable; public function scopeForAuthentication(Builder $query): Builder { return $query->where('active', 1); } }
<?php use Illuminate\Support\Facades\Auth; $user = Auth::user(); // Only include users where "active" is 1
注意,你可以重用另一个现有的作用域。
public function scopeActive(Builder $query): Builder { return $query->where('active', 1); } public function scopeForAuthentication(Builder $query): Builder { return $this->scopeActive($query); }
作为副产品,你还可以根据标准的 Eloquent 方式执行作用域查询。
$user = User::where('email', 'xxx@example.com')->forAuthentication()->firstOrFail();
$user = User::where('email', 'xxx@example.com')->scopes(['forAuthentication'])->firstOrFail();
标准
致谢
许可
MIT 许可下授权。更多信息请参阅 许可文件。