Laravel多租户Passport API执行php artisan passport:install生成OAuth客户端时出现未选择数据库错误
这个问题的核心原因很明确:你的默认数据库连接是tenant,但该连接的database配置为null(符合多租户架构中动态切换租户库的设计),而Passport的OAuth相关表(比如oauth_clients)应该存储在共享的landlord数据库中。当执行passport:install或运行你的PassportSeeder时,Laravel默认使用tenant连接,但这个连接没有指定具体数据库,因此抛出了SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected错误。
下面是具体的解决步骤:
1. 让Passport默认使用Landlord连接
修改app/Providers/AuthServiceProvider.php的boot方法,明确指定Passport使用landlord数据库连接:
public function boot() { $this->registerPolicies(); // 关键:指定Passport操作的数据库连接为landlord Passport::useConnection('landlord'); Passport::hashClientSecrets(); Passport::routes(); }
这会让Passport的所有内部操作(包括命令行的passport:install)都指向landlord数据库,避免使用无指定库的tenant连接。
2. 调整PassportSeeder适配多租户连接
你的PassportSeeder需要明确指定使用landlord连接来创建数据,修改代码如下:
<?php use Illuminate\Database\Seeder; use Laravel\Passport\Client; use Laravel\Passport\PersonalAccessClient; class PassportSeeder extends Seeder { public function run() { // 使用landlord连接创建Personal Access Client $client = Client::on('landlord')->create([ 'name' => 'Personal Access Client', 'secret' => config('passport.personal_access_client.secret'), 'redirect' => 'http://localhost', 'personal_access_client' => true, 'password_client' => false, 'revoked' => false, ]); // 同样使用landlord连接创建关联记录 PersonalAccessClient::on('landlord')->create([ 'client_id' => $client->id, ]); } }
这里用on('landlord')方法强制模型使用指定的数据库连接,确保数据写入正确的库中。
3. 确保Passport迁移已在Landlord库执行
在执行安装命令或seeder之前,先确保Passport的迁移文件已经运行在landlord数据库上:
php artisan migrate --database=landlord
4. 正确执行passport:install命令(可选)
如果你更倾向于用官方命令而不是自定义seeder生成客户端,可以在执行时指定数据库连接:
php artisan passport:install --database=landlord
补充说明
在多租户架构中,Passport的OAuth客户端、令牌等属于系统级共享资源,必须存储在固定的landlord数据库中,而不是动态的租户数据库。通过上述配置,我们强制Passport的所有操作都绑定到landlord连接,彻底解决"未选择数据库"的问题。
内容的提问来源于stack exchange,提问作者Kalpesh Amlani

