You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:10:07