前言:
博主使用的Laravel目前是5.8版本,所以引用相对应的passport版本是7.5.1。
如果你的Laravel版本大于5。可以直接使用passport的9.0版本,这个版本中是直接可以支持多用户认证的,详情请看passport 多用户使用不同模型,发放令牌和验证 | Laravel China 社区
其实国外的网友已经有对此进行讨论,我只针对尝试的其中一种有效方式进行简述:
Passport Multi-Auth · Issue #161 · laravel/passport · GitHub
一、代码
1、新建:app/Http/Middleware/CheckProvider.php
<?php
namespace App\Http\Middleware;
use Closure;
class CheckProvider
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$validator = validator()->make($request->all(), [
'provider' => 'in:admins'
]);
if ($validator->fails()) {
return response()->json([
'error' => 'invalid_provider',
'message' => 'This provider is invalid.'
], 422);
}
if ($request->input('grant_type') === 'password' && $request->input('provider')) {
config(['auth.guards.api.provider' => $request->input('provider')]);
}
return $next($request);
}
}
2、修改:app/Http/Kernel.php
protected $routeMiddleware = [
...
'provider' => \App\Http\Middleware\CheckProvider::class,
];
3、修改:app/Providers/AuthServiceProvider.php
public function boot()
{
...
Passport::routes(null, ['middleware' => 'provider']);
}
4、修改:config/auth.php
'guards' => [
...
'admins' => [
'driver' => 'passport',
'provider' => 'admins',
],
],
'providers' => [
...
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
'passwords' => [
...
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60
],
],
5、新增模型:app/Models/Admin.php
这里非常重要的是使用HasApiTokens, Notifiable这2个Trait
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
class Admin extends Authenticatable
{
use HasApiTokens, Notifiable;
//
}
6、相关路由添加中间件:routes/api.php
Route::middleware('auth:admins')->get('/admin', function (Request $request) {
return Auth::user();
});
7、其他
如果你的admins表是没有使用email字段作为账号,你需要在app/Models/Admin.php下添加
public function findForPassport($username) { return $this->where('username', $username)->first(); }
二、获取token
现在只需将值为admins的provider和其余有效参数传递给/oauth/token。这将根据Admin模型进行身份验证,并返回有效的JWT
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
public function authenticate($guard = '')
{
$client = new Client();
try {
$url = request()->root() . '/oauth/token';
if ($guard) {
$params = array_merge(config('passport.proxy'), [
'username' => request('username'),
'password' => request('password'),
'provider' => $guard,
'scope' => '*',
]);
} else {
$params = array_merge(config('passport.proxy'), [
'username' => request('username'),
'password' => request('password'),
]);
}
$respond = $client->request('POST', $url, ['form_params' => $params,'verify' =>false]);
} catch (RequestException $exception) {
abort(401, $exception->getMessage());
}
if ($respond->getStatusCode() !== 401) {
return json_decode($respond->getBody()->getContents(), true);
}
abort(401, '账号或密码错误');
}
// 调用方法
$token = $this->authenticate('admins');
打印出来的数据:
{
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImYyMTQzZWY5NDVhMGIwZDUwOTkwOWNkNjFhOGM5ZDA1MmYxM2U3ZWMyYzA0YTJmN2MwNmM4MDZjOWUyY2EzOWNhMzQzOGVhOTcyZjIwODg0In0.eyJhdWQiOiIyIiwianRpIjoiZjIxNDNlZjk0NWEwYjBkNTA5OTA5Y2Q2MWE4YzlkMDUyZjEzZTdlYzJjMDRhMmY3YzA2YzgwNmM5ZTJjYTM5Y2EzNDM4ZWE5NzJmMjA4ODQiLCJpYXQiOjE2NjUzMDQ2MzIsIm5iZiI6MTY2NTMwNDYzMiwiZXhwIjoxNjk2ODQwNjMyLCJzdWIiOiIxIiwic2NvcGVzIjpbIioiXX0.R3WC370rnTAPPKEBPeET774y8LlNb3KRyo73wzO5cud_yNh8fSSylh-aLhswutQyDtOUEfLrPfAEDQZ5MJ1F9UXe5tu1rTVj7hkQTS-ObNMMjMXkedOb18Vs9EpoGduOSPaBVfkcjxt50MnboB6lNvpZfDgGL8odp7OtrFYDCuVXtHCeHPqH4a0roZuG-2I9FWJvKWTEH-5X-QRerk6fUc2s6DshEsQDExtL0_tpcFLathOezZjmTeH7mp9Il912uGQced4uYutMWDkz4f_UrTZBxtYtN2YTCvAAYMI0NtQ5t0hdFxKu5beJNF_L22XnRrSFFIbznIk1rrnCSzme5sB8U0lhk2Z5J25bSy0B6VXx9aOgwndLtXXLeSDq1ojn0qkze4GpdbucSrh-_864p6LKbXhv_io4T3isV1H0bCkbGzXz4Lh_Q7llrrtmsmMRm5N1QNhf6kprKG42kP7J7hdAUorPM2V0N3mZlq9l4WLMUjqZi58f13uggrGzd1b18Fa902ySfDWzvgPmsZ_mMvBrB3XCQekmV5SBYJN2nogBGutA9hWMCsyIrrbBXhyvyM18CT3pMeBNVLBqvsCTpFsqnGG3UThc0z17TLRhZ0Pzz3Gquk8NPCDUszkaxEnAjzjHRm5WnTKmLeCFSLFPr9oZU_GPHt_8jfjRV0485XY",
"refresh_token": "def50200d6e3fe6f9538aa0968192750d20a98b40d41a41b8c62f0ce918d0ea064e7ce250745df007387ef997579c659a16ea7c75941300c3c03daa90d7781a3fbc8ccacf9fc37439e7141b1dbea551eff20f864a52963808a49f90f089709b7d9a6346b0fc8e77b3b4be28d8cee0b220213617e7938cfe191ac3bfe84c42a15a9383a1b013297e0a77757159702623b2a44165ae90a64a3460492f7dd854e8cfeda8ea51cbdef082f6c709a777872d3eac00052a74c2a8b3950f0377f76b4ead69b7d4e95a10a6ddd6c57c4ef5308d272f38db19c8818c886d73fd36a7102264df0fc3a1b4f670b689d17030b93d0c0e8e173916ebb8f1a6c1e2b82be5b61a0fa7cf0f2459d7a20fd978c3d42ba55b0ffa527f4c8c0574083316e664914b62331c45fd0e8be4c277e5a455c99c06ea843f8dcd8a5ad5232e2b64111ae59fb82be4a83729d655be975450d4b3dcbd5c7bd1a10983df727f06cd3e351a94789a9cb5264b9"
}