2017-12-01 174 views
11

Używam laravel paszport dla uwierzytelniania API, działa idealnie, kiedy go używać z jednym db, ale daje 401 podczas korzystania z wielu baz danych,laravel paszport daje 401 błąd Nieuwierzytelnione

Co robię:

  • Posiadam db wielo-dzierżawczy, master db ma użytkowników, role i wszystkie tabele Oauth.
  • Gdy utworzę użytkownika z rolą administratora, utworzy on nowy db z nazwą administratora, utworzy sub db z użytkownikami, rolami i wszystkimi tabelami oauth. oauth_clients sub db skopiuje hasło tokena i token dostępu osobistego z głównej bazy danych i wstawi do sub db, a także wstawi client_id w oauth_personal_access_clients.
  • Robię wszystkie procedury, które wykonuje komenda passport:install (jeśli czegoś nie brakuje).

  • Kiedy mogę się zalogować z poświadczeniami z Master db działa idealnie, prawdziwy problem zaczyna się, kiedy mogę się zalogować z poświadczeniami z sub bazie danych, mogę dostać sub db z param client_code którego wejście z email, password przy logowaniu.

  • To pozwala mi się zalogować z sub db ale ja dostać 401 Unauthenticated błąd, uzyskać dostęp do tokenu podczas logowania i mijam Authentication nagłówku Bearer na każde żądanie po zalogowaniu z Angular przodu.

  • Nie wiem, czego mi tu brakuje.

DbConnection Middleware

DbConnection middleware ustawia połączenia na każde żądanie po zalogowaniu

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 ustawia domyślny db w database.php dynamicznie, za to ja dzwonię setDB metoda stworzona na 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); 
    } 

Czy jest możliwe aby użyć passport z 2 różnych dB dla samego kodu?

Laravel 5.4 Passport 4.0 Angular 4.4 w front-end

+0

W jaki sposób dokładnie przełączasz się pomiędzy bazami danych i tym, co znajduje się w twoim nagłówku? To brzmi jak problem z jednym z nich. – tprj29

+0

@ tprj29 Stworzyłem program pośredniczący, który ustawia db config, przekazuję nazwę db w parametrach trasy, nie sądzę, że jej problem z tym, że logowanie działa idealnie, ale problem powstaje po zalogowaniu, zaczyna się podawać błąd 401, używając Angular 4 z przodu –

+0

To naprawdę brzmi jak problem z nagłówkiem, ponieważ nagłówek 'Uwierzytelnianie' jest potrzebny tylko po zalogowaniu. A ponieważ logowanie i otrzymywanie tokena okaziciela działa idealnie według Ciebie. Czy możesz pokazać nam jaką wartość ma twój nagłówek 'Uwierzytelnienie'. – tprj29

Odpowiedz

0

Aby odpowiedzieć na Twoje pytanie: Tak, można!

W naszym middleware robimy niektóre tak:

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

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

To naprawdę brzmi dla mnie, że search_path nie jest ustawiony prawidłowo. To by wyjaśniało, dlaczego masz . Ponieważ Laravel Passport szuka w niewłaściwej bazie danych, w której nie może odnaleźć odpowiedniego tokena w tabeli użytkowników.

Od PostgreSQL docs (https://www.postgresql.org/docs/9.1/static/runtime-config-client.html):

search_path (string)

Zmienna ta określa kolejność, w której schematy są przeszukiwane, gdy obiekt (stół, typ danych, funkcja, etc.) odwołuje się do prostej nazwy bez określonego schematu. Gdy istnieją obiekty o identycznych nazwach w różnych schematach, używany jest pierwszy znaleziony w ścieżce wyszukiwania. Do obiektu, który nie znajduje się w żadnym schemacie w ścieżce wyszukiwania, można się odwoływać tylko podając jego schemat zawierający kwalifikowaną (kropkowaną) nazwę.

+0

Nie używam 'PostgreSQL', używam' Mysql' –

+0

W twoim modelu, który obsługuje kwerendę, możesz zarejestrować połączenie, które jest używane? Myślę, że połączenie nie jest prawidłowo zarządzane w modelach. – tprj29

+0

Jeśli nie używam połączenia "paszportowego" działa idealnie –