Laravel Passport:为默认auth/token路由加中间件及多租户应用中间件切库
给Laravel Passport的auth/token路由添加多租户数据库切换中间件
嘿,我来帮你搞定这个需求!要给Passport默认的auth/token路由加上多租户数据库切换的中间件,咱们得绕开Passport自动注册路由的限制,分几步来实现:
1. 自定义Passport的Token路由
Passport默认的auth/token路由是通过Passport::routes()自动注册的,没法直接给它加中间件。所以咱们得手动注册这个路由,覆盖默认的:
打开routes/api.php,添加以下代码:
use Laravel\Passport\Http\Controllers\TokenController; // 手动注册token路由,指定中间件 Route::post('/auth/token', [TokenController::class, 'issueToken']) ->middleware('tenant.db.switch'); // 这里用你后续注册的中间件名称 // 如果还需要Passport的其他路由,排除默认的token路由即可 Passport::routes(null, ['except' => ['token']]);
记得把原来单独的Passport::routes()注释掉,避免路由冲突。
2. 完善多租户数据库切换中间件
你已经有了中间件的基础代码,咱们把它补全,实现数据库切换逻辑:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\DB; use App\Models\AppConnectionsModel; // 按你的实际模型命名空间调整 class TenantDatabaseSwitch { public function handle($request, Closure $next) { // 获取请求头,Laravel里不用加HTTP_前缀,直接用小写的头名 $passedHeader = $request->header('x-app-location'); // 拉取所有有效的租户头信息 $validHeaders = AppConnectionsModel::pluck('header_val')->toArray(); // 验证头信息合法性 if (empty($passedHeader) || !in_array($passedHeader, $validHeaders)) { return response('Invalid Request.', 403); } // 获取当前租户对应的数据库连接配置 $tenantConfig = AppConnectionsModel::where('header_val', $passedHeader)->first(); if (!$tenantConfig) { return response('Tenant configuration not found.', 404); } // 配置临时的租户数据库连接 config([ 'database.connections.tenant' => [ 'driver' => 'mysql', // 按你的数据库类型调整,比如pgsql 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => $tenantConfig->database_name, 'username' => $tenantConfig->username, 'password' => $tenantConfig->password, 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, ] ]); // 将默认数据库连接切换为租户连接 DB::setDefaultConnection('tenant'); // 如果你只是需要特定模型使用租户连接,也可以在模型里设置$connection = 'tenant' return $next($request); } }
3. 注册中间件
打开app/Http/Kernel.php,把咱们的中间件加到路由中间件数组里:
protected $routeMiddleware = [ // 其他已有的中间件... 'tenant.db.switch' => \App\Http\Middleware\TenantDatabaseSwitch::class, ];
4. 测试验证
用Postman或者curl发送请求到/api/auth/token,记得带上X-App-Location请求头,值为你在AppConnectionsModel中存储的有效header_val。你可以在中间件里加日志,或者在TokenController里打印DB::connection()->getDatabaseName(),确认数据库是否成功切换。
额外注意事项
- 确保租户对应的数据库已经创建,并且数据库用户有足够的权限;
- 如果使用非MySQL数据库(比如PostgreSQL),记得调整连接配置里的
driver、charset等参数; - 可以缓存租户的配置信息,避免每次请求都查询
AppConnectionsModel,提升性能; - 如果其他路由也需要多租户切换,把这个中间件加到对应的路由组即可。
内容的提问来源于stack exchange,提问作者Geoff
相关产品推荐
相关产品推荐

