Laravel-Pass gibt 401 nicht authentifizierten Fehler

Lesezeit: 4 Minuten

Benutzer-Avatar
Nikhil Radadija

Ich verwende den Laravel-Pass für die API-Authentifizierung, es funktioniert perfekt, wenn ich es mit einer DB verwende, gibt es aber 401 bei Verwendung mehrerer Datenbanken,

Was mache ich:

  • Ich habe eine mandantenfähige DB, die Master-DB hat Benutzer, Rollen und alle OAuth-Tabellen.
  • Wenn ich einen Benutzer mit Administratorrolle erstelle, wird eine neue DB mit dem Administratornamen erstellt, es wird eine Unter-DB mit Benutzern, Rollen und allen OAuth-Tabellen erstellt. oauth_clients der Sub-DB kopiert Password Grant Token und Personal Access Token aus der Master-DB und fügt sie in die Sub-DB ein und fügt sie ebenfalls ein client_id in oauth_personal_access_clients.
  • Ich mache alle Verfahren, die passport:install Befehl tut. (Falls ich nichts übersehe).

  • Wenn ich mich mit Anmeldeinformationen aus der Master-DB anmelde, funktioniert es perfekt. Das eigentliche Problem beginnt, wenn ich mich mit Anmeldeinformationen aus der Unterdatenbank anmelde, ich kann die Unter-DB aus einem Parameter abrufen client_code mit dem ich eintippe email,password beim Einloggen.

  • Es erlaubt mir, mich von der Sub-DB anzumelden, aber ich bekomme 401 Unauthenticated Fehler, erhalten Sie Zugriffstoken während der Anmeldung und ich passe Authentication Kopfzeile mit Bearer bei jeder Anfrage nach Login aus Angular Vorderseite.

  • Weiß nicht, was ich hier vermisse.

DBConnection-Middleware

DBConnection-Middleware stellt die Verbindung bei jeder Anfrage nach der Anmeldung ein,

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 setzt die Standard-DB in database.php dynamisch, dafür rufe ich setDB Methode erstellt am 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);
  }

Ist es möglich zu verwenden passport mit 2 verschiedenen DB für gleichen Code?

Laravel 5.4
Passport 4.0
Angular 4.4 im Frontend

  • Wie wechseln Sie zwischen Datenbanken und was genau befindet sich in Ihrem Header? Es hört sich nach einem Problem mit einem davon an.

    – tprj29

    1. Dezember 2017 um 14:46 Uhr

  • @ tprj29 Ich habe eine Middleware erstellt, die db config festlegt, ich übergebe einen db-Namen in route params, ich glaube nicht, dass das Problem damit besteht, da die Anmeldung perfekt funktioniert, aber nach der Anmeldung tritt ein Problem auf, es beginnt mit Angular 4 einen 401-Fehler zu geben auf Vorderseite

    – Nikhil Radadija

    1. Dezember 2017 um 14:54 Uhr


  • Das klingt wirklich nach einem Kopfzeilenproblem, weil die Kopfzeile Authentication wird nur nach dem Login benötigt. Und da die Anmeldung und das Abrufen des Inhaber-Tokens Ihrer Meinung nach perfekt funktionieren. Können Sie uns zeigen, welchen Wert Ihr Header hat Authentication hat.

    – tprj29

    1. Dezember 2017 um 15:00 Uhr

  • @tprj29 Die Autorisierung ist die gleiche wie bei der Anmeldung

    – Nikhil Radadija

    1. Dezember 2017 um 15:23 Uhr

  • Code würde helfen, weil es ohne anny Codesnips schwer zu erkennen ist, wo es schief geht

    – tprj29

    1. Dezember 2017 um 15:42 Uhr

Benutzer-Avatar
tprj29

Um deine Frage zu beantworten: Ja, du kannst!

In unserer Middleware machen wir einiges wie folgt:

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

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

Es klingt wirklich für mich, dass Ihr search_path nicht richtig eingerichtet ist. Dies würde erklären, warum Sie eine bekommen 401. Weil Laravel Passport in der falschen Datenbank sucht, in der es nicht das richtige Token in Ihrer Benutzertabelle finden kann.

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

Suchpfad (Zeichenfolge)

Diese Variable gibt die Reihenfolge an, in der Schemas durchsucht werden, wenn auf ein Objekt (Tabelle, Datentyp, Funktion usw.) mit einem einfachen Namen ohne Angabe eines Schemas verwiesen wird. Wenn Objekte mit identischen Namen in verschiedenen Schemas vorhanden sind, wird das im Suchpfad zuerst gefundene verwendet. Auf ein Objekt, das sich in keinem der Schemas im Suchpfad befindet, kann nur verwiesen werden, indem das enthaltende Schema mit einem qualifizierten (gepunkteten) Namen angegeben wird.

  • Ich benutze nicht PostgreSQLIch benutze Mysql

    – Nikhil Radadija

    6. Dezember 2017 um 5:04 Uhr

  • Können Sie in Ihrem Modell, das die Abfrage verarbeitet, die verwendete Verbindung protokollieren? Ich denke, die Verbindung wird innerhalb der Modelle nicht richtig verwaltet.

    – tprj29

    7. Dezember 2017 um 9:11 Uhr

  • Wenn ich nicht benutze passport Verbindung funktioniert einwandfrei

    – Nikhil Radadija

    7. Dezember 2017 um 10:24 Uhr

Dies ist ein CORS-Problem. Die OPTIONS-Anforderung liefert keine Autorisierungsheader.

Wenn sich der Ursprung vom Host unterscheidet, sendet der Browser OPTIONS vor jeder anderen Anfrage.

Laravel wird mit dem Status 401 antworten, wenn die CORS-Middleware nicht eingerichtet ist.

Wenn sich also bei der RESTful-Architektur der Client-App-Host vom API-Host unterscheidet, müssen Sie CORS-Middleware verwenden.

Sie können diesen verwenden:
barryvdh/laravel-cors

$ composer require barryvdh/laravel-cors

Beispiel:

App\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', '[email protected]');
});

Wenn die CORS-Middleware ordnungsgemäß funktioniert, erhält ein Browser den Status 200 bei der OPTIONS-Anfrage und löst die erste Anfrage mit einer Nutzlast aus.

  • Er sendet keine OPTIONS Anfrage – seine Middleware prüft Methoden Sonstiges als OPTIONS

    – Mike Harrison

    8. Januar 2019 um 12:37 Uhr

1121320cookie-checkLaravel-Pass gibt 401 nicht authentifizierten Fehler

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy