Laravel auth 中间件使用了错误的数据库
Laravel auth middleware using wrong database
在 config/database.php
中我有两个连接:mysql
和 website
。两者都连接到同一台主机,只是数据库不同。默认为 mysql
.
我创建了一个名为 SetupWebsite
的中间件,它检查传入域是否存在于默认连接的数据库中。如果是,它将使用以下代码填充 website
与正确数据库的连接:
config(['database.connections.website.database' => $database]);
然后,它将默认连接切换为 website
:
config(['database.default' => 'website']);
我通过从数据库中检索仅存在于 website
连接中的值来验证默认连接现在是 website
。我还可以在 website
连接中登录用户帐户。现在,当我设置以下路线时:
Route::get('admin', function () {
return 'Welcome to the dashboard!';
})->middleware('auth');
我在成功登录后去了那里,收到 'tbl_users does not exists' 的错误消息,我看到它使用 mysql
连接来检查用户是否已通过身份验证。我 运行 不知道如何告诉 Laravel 我正在使用另一个数据库连接。小提示:我没有缓存配置。
更新
当我在Illuminate\Auth\Middleware\Authenticate::class
的构造函数中添加如下代码时:
DB::setDefaultConnection('website');
我收到没有选择数据库的错误消息,这意味着在我的 SetupWebsite
中间件发挥作用之前,身份验证中间件是 'created'。有什么建议可以解决这个问题吗?
哇哦!我找到了解决方法。就像我在问题中所说的那样,看起来 auth 中间件是在我自己的中间件之前设置的,这导致 auth 中间件使用启动时已知的默认连接,即 mysql
。所以我决定将 auth 中间件复制粘贴到一个名为 AwesomeAuthMiddleware
的新中间件,然后改用那个中间件。成功了!
对于发现此问题的其他人,我 运行 遇到与 Laravel 护照和多租户相同的问题。我也有一个通用数据库,每个租户都有另一个数据库。有一个比复制上面的 auth 中间件更简单的解决方案。只需使用 Laravel.
的中间件优先级
在 Kernel.php
中,您已经获得 属性 $middlewarePriority
,只需在 Laravel 的身份验证中间件之前添加您的数据库更改中间件。
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// Always connect to the DB first, before executing AUTH middleware
\App\Http\Middleware\ConnectToDatabase::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
在 config/database.php
中我有两个连接:mysql
和 website
。两者都连接到同一台主机,只是数据库不同。默认为 mysql
.
我创建了一个名为 SetupWebsite
的中间件,它检查传入域是否存在于默认连接的数据库中。如果是,它将使用以下代码填充 website
与正确数据库的连接:
config(['database.connections.website.database' => $database]);
然后,它将默认连接切换为 website
:
config(['database.default' => 'website']);
我通过从数据库中检索仅存在于 website
连接中的值来验证默认连接现在是 website
。我还可以在 website
连接中登录用户帐户。现在,当我设置以下路线时:
Route::get('admin', function () {
return 'Welcome to the dashboard!';
})->middleware('auth');
我在成功登录后去了那里,收到 'tbl_users does not exists' 的错误消息,我看到它使用 mysql
连接来检查用户是否已通过身份验证。我 运行 不知道如何告诉 Laravel 我正在使用另一个数据库连接。小提示:我没有缓存配置。
更新
当我在Illuminate\Auth\Middleware\Authenticate::class
的构造函数中添加如下代码时:
DB::setDefaultConnection('website');
我收到没有选择数据库的错误消息,这意味着在我的 SetupWebsite
中间件发挥作用之前,身份验证中间件是 'created'。有什么建议可以解决这个问题吗?
哇哦!我找到了解决方法。就像我在问题中所说的那样,看起来 auth 中间件是在我自己的中间件之前设置的,这导致 auth 中间件使用启动时已知的默认连接,即 mysql
。所以我决定将 auth 中间件复制粘贴到一个名为 AwesomeAuthMiddleware
的新中间件,然后改用那个中间件。成功了!
对于发现此问题的其他人,我 运行 遇到与 Laravel 护照和多租户相同的问题。我也有一个通用数据库,每个租户都有另一个数据库。有一个比复制上面的 auth 中间件更简单的解决方案。只需使用 Laravel.
的中间件优先级在 Kernel.php
中,您已经获得 属性 $middlewarePriority
,只需在 Laravel 的身份验证中间件之前添加您的数据库更改中间件。
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// Always connect to the DB first, before executing AUTH middleware
\App\Http\Middleware\ConnectToDatabase::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];