LaravelパスポートをAPI認証に使用しています。1つのDBで使用すると完全に機能しますが、複数のデータベースを使用すると_401
_が得られます。
私がやっていること:
oauth_clients
_がコピーされますマスターDBからのパスワード付与トークンとパーソナルアクセストークン、およびサブDBへの挿入、および_client_id
_への_oauth_personal_access_clients
_の挿入。_passport:install
_コマンドが実行するすべての手順を実行しています。 (私が何かを逃していない場合)。
マスターDBからの資格情報でログインすると完全に機能します。実際の問題は、サブデータベースから資格情報でログインしたときに始まります。email
で入力したパラメーター_client_code
_からサブDBを取得できます。ログイン中のpassword
.
サブDBからログインできますが、ログイン中に_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
はデフォルトのDBを_database.php
_に動的に設定します。そのため、__($ OME] _で作成された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);
}
_
同じコードに対して2つの異なるDBでpassport
を使用することは可能ですか?
_Laravel 5.4
_フロントエンドに_Passport 4.0
_ _Angular 4.4
_
あなたの質問に答えるには:はい、できます!
ミドルウェアでは、次のようにしています。
config([
'database.connections.tenant.schema' => $tenant
]);
DB::connection('tenant')->statement("SET search_path = $tenant");
Search_pathが正しく設定されていないように思えます。これは、401を取得する理由を説明します。 Laravel Passportが間違ったデータベースを検索しているため、ユーザーテーブルで適切なトークンを見つけることができないためです。
PostgreSQL docs( https://www.postgresql.org/docs/9.1/static/runtime-config-client.html )から:
search_path(文字列)
この変数は、スキーマが指定されていない単純な名前でオブジェクト(テーブル、データ型、関数など)が参照される場合に、スキーマが検索される順序を指定します。異なるスキーマに同じ名前のオブジェクトがある場合、検索パスで最初に見つかったオブジェクトが使用されます。検索パス内のどのスキーマにも含まれていないオブジェクトは、その含まれているスキーマを修飾(ドット付き)名で指定することによってのみ参照できます。
これはCORSの問題です。 OPTIONSリクエストは、Authorizationヘッダーを配信しません。
オリジンがホストと異なる場合、ブラウザは他のリクエストの前にOPTIONSを送信します。
CORSミドルウェアがセットアップされていない場合、Laravelはステータス401で応答します。
したがって、RESTfulアーキテクチャでは、クライアントアプリのホストがAPIのホストと異なる場合、CORSミドルウェアを使用する必要があります。
これを使用できます: barryvdh/laravel-cors
$ composer require barryvdh/laravel-cors
例:
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', 'UserController@authenticate');
});
CORSミドルウェアが適切に機能する場合、ブラウザはOPTIONSリクエストでステータス200を受け取り、ペイロードを使用して最初のリクエストを起動します。