islem-kms / l5-mauth-pass
A
v2.0.0
2020-10-21 15:19 UTC
Requires
- php: ^7.2
- laravel/passport: ^8.0
Requires (Dev)
- mockery/mockery: ^1.0
- orchestra/database: ^3.5
- orchestra/testbench: ~3.5
This package is auto-updated.
Last update: 2024-09-21 23:35:14 UTC
README
为 Laravel Passport 添加多身份验证支持
兼容性
安装和配置
- 使用 composer 安装
composer require islem-kms/l5-mauth-pass
- 如果你使用的是小于 5.5 版本的 Laravel,你需要在
config/app.php
中 添加 提供者
'providers' => [ ... IslemKms\PassportMultiauth\Providers\MultiauthServiceProvider::class, ],
- 迁移数据库以创建
oauth_access_token_providers
表
php artisan migrate
- 在
config/auth.php
中使用继承自Authenticatable
类的模型添加新的提供者,并使用HasApiTokens
特性。
例如:
- 配置你的模型
<?php use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; use Laravel\Passport\HasApiTokens; class Admin extends Authenticatable { use Notifiable, HasApiTokens;
- 以及你的
config/auth.php
提供者
<?php return [ ... 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], // ** New provider** 'admins' => [ 'driver' => 'eloquent', 'model' => App\Administrator::class, ], ], ];
- 在
config/auth.php
的 guards 数组中使用驱动passport
和上面添加的提供者添加一个新的guard
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], // ** New guard ** 'admin' => [ 'driver' => 'passport', 'provider' => 'admins', ], ]
- 在
app/Http/Kernel
的$middlewareGroups
属性上注册中间件AddCustomProvider
和ConfigAccessTokenCustomProvider
。
class Kernel extends HttpKernel { ... /** * The application's route middleware groups. * * @var array */ protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ 'throttle:60,1', 'bindings', \Barryvdh\Cors\HandleCors::class, 'custom-provider', ], 'custom-provider' => [ \IslemKms\PassportMultiauth\Http\Middleware\AddCustomProvider::class, \IslemKms\PassportMultiauth\Http\Middleware\ConfigAccessTokenCustomProvider::class, ] ]; ... }
- 在
AuthServiceProvider
中封装具有注册中间件的访问令牌的路由
use Route; use Laravel\Passport\Passport; class AuthServiceProvider extends ServiceProvider { ... /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); Passport::routes(); // Middleware `api` that contains the `custom-provider` middleware group defined on $middlewareGroups above Route::group(['middleware' => 'api'], function () { Passport::routes(function ($router) { return $router->forAccessTokens(); }); }); } ... }
可选: 发布迁移
php artisan vendor:publish
并选择提供者 IslemKms\PassportMultiauth\Providers\MultiauthServiceProvider
使用方法
- 在
/oauth/token
请求中添加provider
参数
POST /oauth/token HTTP/1.1
Host: localhost
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache
{
"username":"user@domain.com",
"password":"password",
"grant_type" : "password",
"client_id": "client-id",
"client_secret" : "client-secret",
"provider" : "admins"
}
- 你可以根据需要将 guards 传递给
auth
中间件。例如:
Route::group(['middleware' => ['api', 'auth:admin']], function () { Route::get('/admin', function ($request) { // Get the logged admin instance return $request->user(); // You can use too `$request->user('admin')` passing the guard. }); });
使用 api
guard 的例子与使用 admin
的例子相同。
- 你可以将多个 guards 传递给
auth
中间件。
注意: 要传递多个,您需要在 guards 的末尾传递 api
guard,并在 $request->user()
方法中将 guard api
作为参数传递。例如:
// `api` guard on end of guards separated by comma Route::group(['middleware' => ['api', 'auth:admin,api']], function () { Route::get('/admin', function ($request) { // Passing `api` guard to `$request->user()` method // The instance of user authenticated (Admin or User in this case) will be returned return $request->user('api'); }); });
刷新令牌
- 在
/oauth/token
请求中添加provider
参数
POST /oauth/token HTTP/1.1
Host: localhost
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache
{
"grant_type" : "refresh_token",
"client_id": "client-id",
"client_secret" : "client-secret",
"refresh_token" : "refresh-token",
"provider" : "admins"
}
使用作用域
- 如果您在相同路由上使用多个 guard,请使用以下包中间件而不是使用来自
Laravel\Passport
的scope
和scopes
中间件。
protected $routeMiddleware = [ 'multiauth.scope' => \IslemKms\PassportMultiauth\Http\Middleware\MultiAuthCheckForAnyScope::class, 'multiauth.scopes' => \IslemKms\PassportMultiauth\Http\Middleware\MultiAuthCheckScopes::class, ];
这些中间件与 Laravel\Passport
中间件相同,但在 request->user()
对象上使用 api
guard。
用户示例
Route::group([ 'middleware' => ['auth:admin,api', 'multiauth.scope:read-books'] ], function ($request) { return $request->user('api'); });
单元测试
如果您在请求中使用多身份验证,您只需将一个 Authenticatable
对象传递给 Laravel\Passport\Passport::actingAs()
即可。例如:
- 您有一个具有多身份验证的路由
Route::group(['middleware' => 'auth:admin,api'], function () { Route::get('/foo', function ($request) { return $request->user('api'); // Return user or admin }); });
- 在您的测试中,只需将您的实体传递给
Passport::actingAs()
use App\User; use App\Admin; use Laravel\Passport\Passport; class MyTest extends TestCase { public function testFooAdmin() { $admin = factory(Admin::class)->create(); Passport::actingAs($admin); // When you use your endpoint your admin will be returned $this->json('GET', '/foo') ->assertStatus(200) ->assertJson([ 'data' => [ 'id' => 1, 'name' => 'Admin', 'email' => 'admin@admin.com' ] ]); } public function testFooUser() { $user = factory(User::class)->create(); Passport::actingAs($user); // When you use your endpoint your user will be returned $this->json('GET', '/foo') ->assertStatus(200) ->assertJson([ 'data' => [ 'id' => 1, 'name' => 'User', 'email' => 'user@user.com' ] ]); } }
- 如果您的路由只有一个 guard
Route::group(['middleware' => 'auth:admin'], function () { Route::get('/foo', function ($request) { return $request->user(); // Return admin }); });
- 在您的测试中,只需将您的实体、作用域和 guard 传递给
Passport::actingAs()
use App\User; use App\Admin; use Laravel\Passport\Passport; class MyTest extends TestCase { public function testFooAdmin() { $admin = factory(Admin::class)->create(); Passport::actingAs($admin, [], 'admin'); // When you use your endpoint your admin will be returned $this->json('GET', '/foo') ->assertStatus(200) ->assertJson([ 'data' => [ 'id' => 1, 'name' => 'Admin', 'email' => 'admin@admin.com' ] ]); } }