我正在使用Laravel Passport进行API身份验证,当我与一个db一起使用时,它可以很好地工作,但是在使用多个数据库时给出401
,
我在做什么:
- 我有一个多租户数据库,主数据库具有用户,角色和所有OAUTH表。
- 当我创建具有管理员角色的用户时,它将创建带有admin名称的新DB,它将创建带有用户,角色和所有OAUTH表的子数据库。Sub DB的
oauth_clients
将从主DB复制密码授予令牌和个人访问令牌,并在Sub DB中插入,也将client_id
插入oauth_personal_access_clients
。 -
我正在执行
passport:install
命令执行的所有过程。(如果我没有错过任何东西)。 -
当我使用Master DB登录凭证时,它可以完美地工作,真正的问题开始于我从sub-database登录凭据时,我可以从param
client_code
中获得sub db,我使用email
输入, CC_7,login le login the login。 -
它允许我从sub db登录,但我遇到
401 Unauthenticated
错误,在登录时获取访问令牌,我在每个请求中通过Bearer
通过CC_11通过Angular
Front登录后。 -
不知道我在这里缺少什么。
DBConnection Middleware
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('AppHttpControllersController')->setDB(AppHelper::DB_PREFIX.$this->access_code);
} else {
app('AppHttpControllersController')->setDB(AppHelper::DB_DEFAULT);
}
}
return $next($request);
}
DBConnection
在database.php
中设置默认DB,为此,我在Controller.php
上创建的setDB
方法
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
与2个不同DB一起使用相同代码?
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(string)
此变量指定在对象(表,数据类型,函数等)中通过未指定模式的简单名称引用该模式的顺序。当不同模式中有相同名称的对象时,使用搜索路径中的首先找到的对象。搜索路径中不在任何模式中的对象只能通过指定包含其包含的模式(点缀)名称来引用。
这是CORS问题。选项请求不提供授权标题。
如果原点与主机不同,则浏览器将在任何其他请求之前发送选项。
Laravel如果未设置CORS中间件,将以状态401回答。
因此,使用RESTFUL架构,如果客户端应用程序主机与API主机不同,则必须使用CORS中间件。
您可以使用此:barryvdh/laravel-cors
$ composer require barryvdh/laravel-cors
示例:
app http kernel.php
protected $routeMiddleware = [
...
'auth.cors' => BarryvdhCorsHandleCors::class,
...
];
web.php
Route::group([
'prefix' => 'api',
'middleware' => [
'auth.cors'
]
], function () {
Route::post('user/authenticate', 'UserController@authenticate');
});
如果CORS中间件正常工作,则浏览器应在选项请求中获得200个状态,并用有效载荷发射初始请求。