Паспорт Laravel выдает ошибку 401 Unauthenticated

Я использую паспорт Laravel для аутентификации API, он отлично работает, когда я использую его с одной БД, но дает 401 при использовании нескольких баз данных,

Что я делаю:

  • У меня есть мультитенантная БД, в основной БД есть пользователи, роли и все таблицы OAuth.
  • Когда я создаю пользователя с ролью администратора, он создаст новую БД с именем администратора, он создаст вспомогательную БД с пользователями, ролями и всей таблицей OAuth. oauth_clients подчиненной БД скопирует токен предоставления пароля и токен персонального доступа из основной БД и вставит в подчиненную БД, а также вставит client_id в oauth_personal_access_clients.
  • Я выполняю все процедуры, которые выполняет команда passport:install. (Если я что-то не упускаю).

  • Когда я вхожу в систему с учетными данными из главной БД, она работает отлично, настоящая проблема начинается, когда я вхожу в систему с учетными данными из под-базы данных, я могу получить дополнительную БД из параметра client_code, который я ввожу с помощью _7 _, _ 8_ при входе в систему.

  • Это позволяет мне входить в систему из дополнительной БД, но я получаю 401 Unauthenticated ошибку, получаю токен доступа при входе в систему и передаю Authentication заголовок с Bearer при каждом запросе после входа в Angular на передней панели.

  • Не знаю, что мне здесь не хватает.

ПО промежуточного слоя DBConnection

Промежуточное ПО DBConnection устанавливает соединение при каждом запросе после входа в систему,

public function handle($request, Closure $next)
    {
        if ( $request->method() != 'OPTIONS' ) {            
            $this->access_code = $request->header('access-code'); 
            if ( $this->access_code != '' && $this->access_code != 'sa'  ) {
                app('App\Http\Controllers\Controller')->setDB(AppHelper::DB_PREFIX.$this->access_code);
            } else {
                app('App\Http\Controllers\Controller')->setDB(AppHelper::DB_DEFAULT);
            }
        }
        return $next($request);
    }

DBConnection устанавливает БД по умолчанию в database.php динамически, для этого я вызываю setDB метод, созданный Controller.php

setDB Controller.php

public function setDB($database='') {
      $config = app()->make('config');
      $connections = $config->get('database.connections');
      $default_connection = $connections[$config->get('database.default')];
      $new_connection = $default_connection;
      $new_connection['database'] = $database;
      $config->set('database.connections.'.$database, $new_connection);
      $config->set('database.default', $database);
  }

Можно ли использовать passport с двумя разными БД для одного и того же кода?

Laravel 5.4 Passport 4.0 Angular 4.4 во внешнем интерфейсе


person Nikhil Radadiya    schedule 01.12.2017    source источник
comment
Как вы переключаетесь между базами данных и что именно находится внутри вашего заголовка? Похоже, проблема с одним из них.   -  person tprj29    schedule 01.12.2017
comment
@ tprj29 Я создал промежуточное ПО, которое устанавливает конфигурацию db, я передаю имя db в параметрах маршрута, я не думаю, что это проблема с этим, поскольку вход в систему работает отлично, но проблема возникает после входа в систему, она начинает выдавать ошибку 401, используя Angular 4 на фронте   -  person Nikhil Radadiya    schedule 01.12.2017
comment
Это действительно похоже на проблему с заголовком, потому что заголовок Authentication нужен только после входа в систему. И поскольку вход в систему и получение токена на предъявителя, по вашему мнению, отлично работает. Вы можете показать нам, какое значение имеет ваш заголовок Authentication.   -  person tprj29    schedule 01.12.2017
comment
@ tprj29 Авторизация такая же, как и при входе в систему   -  person Nikhil Radadiya    schedule 01.12.2017
comment
код поможет, потому что трудно понять, где что-то пошло не так, без каких-либо замечаний   -  person tprj29    schedule 01.12.2017
comment
@ tprj29 Код добавлен к вопросу, вы можете проверить?   -  person Nikhil Radadiya    schedule 04.12.2017
comment
попробуйте добавить запрос search_path, подробности см. в моем ответе.   -  person tprj29    schedule 05.12.2017
comment
Паспорт Laravel работает только с пользователем в качестве провайдера. Даже если вы получаете токен, добавляя указанные выше изменения с помощью PasswordGrant и UserRepository, пока вы используете вызов API для Post и получаете запросы, не работают с измененным поставщиком паспорта, отличным от User. Лучше создать мульти-аутентификацию с драйвером сеанса, если это необходимо как поставщикам, так и клиентам. пусть модель «Пользователь» только для паспорта, столбцы таблицы которого поддерживают admin, API, vendor и т. д. Репо здесь github. com / storebuzz / laravel-multiAuth.   -  person Anand Pandey    schedule 08.12.2017
comment
github.com/jsdecena/laravel-passport-mutiauth   -  person Anand Pandey    schedule 08.12.2017
comment
Возможно, вам нужно использовать User, который расширяется от Authenticatable и использовать черты HasApiTokens. Кроме того, возможно, вам потребуется разработать собственную аутентификацию для входа в систему.   -  person David L    schedule 02.03.2018
comment
Эта проблема может быть связана с порядком промежуточного программного обеспечения, убедитесь, что DBConnectionMiddleware находится перед промежуточным программным обеспечением для проверки подлинности паспорта.   -  person Mike Harrison    schedule 08.01.2019
comment
Если вы используете Auth :: try, работает нормально?   -  person Fabio William Conceição    schedule 29.05.2019


Ответы (2)


Чтобы ответить на ваш вопрос: Да, вы можете!

В нашем промежуточном программном обеспечении мы делаем что-то вроде этого:

config([
  'database.connections.tenant.schema' => $tenant
]);

DB::connection('tenant')->statement("SET search_path = $tenant");

Мне действительно кажется, что ваш search_path неправильно настроен. Это могло бы объяснить, почему вы получаете 401. Поскольку Laravel Passport ищет в неправильной базе данных, в которой он не может найти правильный токен в вашей таблице пользователей.

Из документов PostgreSQL (https://www.postgresql.org/docs/9.1/static/runtime-config-client.html):

search_path (строка)

Эта переменная определяет порядок, в котором выполняется поиск схем, когда объект (таблица, тип данных, функция и т. Д.) Упоминается по простому имени без указания схемы. Когда в разных схемах есть объекты с одинаковыми именами, используется тот, который был найден первым в пути поиска. На объект, которого нет ни в одной из схем в пути поиска, можно ссылаться, только указав содержащую его схему с квалифицированным (пунктирным) именем.

person tprj29    schedule 05.12.2017
comment
Я не использую PostgreSQL, я использую Mysql - person Nikhil Radadiya; 06.12.2017
comment
В вашей модели, которая обрабатывает запрос, можете ли вы зарегистрировать используемое соединение? Я думаю, что соединение внутри моделей не управляется должным образом. - person tprj29; 07.12.2017
comment
Если я не использую passport соединение работает отлично - person Nikhil Radadiya; 07.12.2017

Это проблема CORS. Запрос OPTIONS не доставляет заголовки авторизации.

Если источник отличается от хоста, браузер отправит ОПЦИИ перед любым другим запросом.

Laravel ответит статусом 401, если промежуточное ПО CORS не настроено.

Итак, с архитектурой RESTful, если хост клиентского приложения отличается от хоста API, вы должны использовать промежуточное ПО CORS.

Вы можете использовать это: barryvdh / laravel-cors

$ composer require barryvdh/laravel-cors

Пример:

Приложение \ Http \ Kernel.php

protected $routeMiddleware = [
    ...
    'auth.cors' => \Barryvdh\Cors\HandleCors::class,
    ...
];

web.php

Route::group([
    'prefix' => 'api',
    'middleware' => [
        'auth.cors'
    ]
], function () {
    Route::post('user/authenticate', 'UserController@authenticate');
});

Если промежуточное ПО CORS работает правильно, браузер должен получить статус 200 по запросу OPTIONS и запустить начальный запрос с полезной нагрузкой.

person Emma Paulowicz    schedule 15.03.2018
comment
Он не отправляет OPTIONS запрос - его промежуточное ПО проверяет методы другие, кроме OPTIONS - person Mike Harrison; 08.01.2019