Laravel 5.8如何用Passport API认证实现Web中间件路由鉴权?
当然可行!Laravel的Guard机制就是为了灵活适配各种认证场景而生的,刚好能解决你这种用API凭证给web路由创建会话的需求。我给你梳理下具体怎么实现:
核心思路
你的app站点没有本地数据库,没法用默认的session guard直接查询用户数据,所以我们需要自定义一个Guard:让它通过调用core站点的API来验证用户凭证,验证通过后把用户信息存在app本地的会话里,这样web路由就能通过这个Guard识别用户的登录状态了。
具体实现步骤
1. 创建自定义Guard类
先在app/Auth目录下新建一个ApiSessionGuard.php文件(如果Auth目录不存在就手动创建)。这个类要实现Laravel的Guard接口,核心是处理用户获取、凭证验证、登录登出这些逻辑:
<?php namespace App\Auth; use Illuminate\Auth\GuardHelpers; use Illuminate\Contracts\Auth\Guard; use Illuminate\Http\Client\PendingRequest; use Illuminate\Support\Facades\Http; class ApiSessionGuard implements Guard { use GuardHelpers; protected $request; public function __construct($request) { $this->request = $request; } // 获取当前登录用户:先从session取,取不到就返回null public function user() { if (!is_null($this->user)) { return $this->user; } $userData = $this->request->session()->get('api_user'); if ($userData) { // 把session里的数组转成User模型(只是个数据容器) $this->user = new \App\User($userData); return $this->user; } return null; } // 验证用户凭证:调用core的登录API public function validate(array $credentials = []) { $response = $this->getApiClient()->post('/api/login', $credentials); if ($response->successful()) { $userData = $response->json()['user']; // 把用户信息存入session $this->request->session()->put('api_user', $userData); $this->user = new \App\User($userData); return true; } return false; } // 手动登录用户:比如拿到API返回的用户信息后直接创建会话 public function login($user) { $this->request->session()->put('api_user', $user->toArray()); $this->setUser($user); } // 登出用户:清除session,可选调用core的登出API销毁token public function logout() { $this->request->session()->forget('api_user'); $this->user = null; $this->getApiClient()->post('/api/logout'); } // 配置HTTP客户端,带上Passport客户端凭证 protected function getApiClient(): PendingRequest { return Http::withHeaders([ 'Accept' => 'application/json', ])->withBasicAuth( config('services.core.client_id'), config('services.core.client_secret') )->baseUrl(config('services.core.url')); } }
2. 配置Guard与Provider
修改config/auth.php,添加自定义的guard和对应的用户provider:
'guards' => [ 'web' => [ 'driver' => 'api_session', // 指定我们自定义的guard驱动 'provider' => 'api_users', ], // 保留原来的api guard 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ], 'providers' => [ 'api_users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], ],
3. 注册Guard驱动
在App\Providers\AppServiceProvider的boot方法里,注册我们自定义的Guard驱动:
use App\Auth\ApiSessionGuard; use Illuminate\Support\Facades\Auth; public function boot() { Auth::extend('api_session', function ($app, $name, array $config) { return new ApiSessionGuard($app['request']); }); }
4. 调整App站点的User模型
因为App站点没有数据库,我们的User模型不需要继承Eloquent的Model,改成一个简单的数据容器即可:
<?php namespace App; class User { protected $attributes = []; public function __construct(array $attributes = []) { $this->attributes = $attributes; } public function __get($key) { return $this->attributes[$key] ?? null; } public function toArray() { return $this->attributes; } // 实现Guard需要的身份标识方法 public function getAuthIdentifier() { return $this->attributes['id']; } }
5. 给Web路由添加认证中间件
现在你的web路由就可以直接使用auth:web中间件了,比如:
Route::middleware('auth:web')->group(function () { Route::get('/dashboard', function () { return view('dashboard', ['user' => auth()->user()]); }); });
一些注意事项
- 确保App站点的session配置正常(比如用文件或Redis存储,不需要数据库)
- 可以在自定义Guard里添加定期验证逻辑,比如每次请求时调用core的API检查用户会话是否有效
- 如果core站点的用户信息更新了,App站点session里的信息不会自动同步,你可以在需要的时候重新调用API拉取并更新session
内容的提问来源于stack exchange,提问作者Riza
相关产品推荐
相关产品推荐

