Промежуточное ПО Laravel для аутентификации использует неправильную базу данных

В 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 не существует», и я вижу, что он использует соединение mysql для проверки подлинности пользователя. У меня закончились идеи, как сообщить Laravel, что я использую другое подключение к базе данных. FIY: Я не кэшировал конфигурацию.

ОБНОВИТЬ

Когда я добавляю следующий код в конструктор Illuminate\Auth\Middleware\Authenticate::class:

DB::setDefaultConnection('website');

Я получаю сообщение об ошибке, что база данных не выбрана, что означает, что промежуточное ПО аутентификации «создано» до того, как мое промежуточное ПО SetupWebsite сделает свое волшебство. Любые предложения, как я могу это исправить?


person SomeCode    schedule 08.12.2016    source источник


Ответы (2)


Упс! Я нашел обходной путь для этого. Как я уже сказал в своем вопросе, похоже, что промежуточное ПО для аутентификации настраивается раньше, чем мои собственные промежуточные ПО, что приводит к тому, что промежуточное ПО для аутентификации использует соединение по умолчанию, известное при запуске, то есть mysql. Поэтому я решил скопировать и вставить промежуточное программное обеспечение аутентификации в новое промежуточное программное обеспечение с именем что-то вроде AwesomeAuthMiddleware и использовать его вместо этого. Это сработало!

person SomeCode    schedule 09.12.2016

Для других людей, обнаруживших это, я столкнулся с той же проблемой с Laravel Passport и мультитенантностью. У меня также есть общая база данных с другой базой данных для каждого арендатора. Есть более простое решение, чем копирование промежуточного программного обеспечения авторизации выше. Просто используйте приоритеты промежуточного программного обеспечения 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,
];
person Thomas Roovers    schedule 04.01.2019