Laravel护照给401未经验证的错误 [英] Laravel passport gives 401 Unauthenticated error
问题描述
我正在使用Laravel护照进行API身份验证,当我将其与一个数据库一起使用时,它可以很好地工作,但是当使用多个数据库时,它会给出401
,
我在做什么:
- 我有一个多租户数据库,主数据库有用户,角色和所有OAuth表.
- 当我创建一个具有管理员角色的用户时,它将创建一个具有管理员名称的新数据库,它将创建一个具有用户,角色和所有OAuth表的子数据库.子数据库的
oauth_clients
将从主数据库复制密码授予令牌和个人访问令牌,然后插入子数据库,并在oauth_personal_access_clients
中插入client_id
. -
我正在执行
passport:install
命令所执行的所有过程. (如果我没有丢失任何东西). -
当我使用主数据库中的凭据登录时,它可以正常运行,当我使用子数据库中的凭据登录时,真正的问题就开始了,我可以从用
email
输入的参数client_code
中获取子DB. ,password
登录时. -
它允许我从子数据库登录,但出现
401 Unauthenticated
错误,登录时获取Access令牌,并且从Angular
前端登录后,在每次请求时都将Authentication
标头和Bearer
传递给. p> -
不知道我在这里想念什么.
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
中的默认数据库,为此,我正在调用在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
在前端
这是CORS问题. OPTIONS请求未提供授权标头.
如果来源不同于主机,则浏览器将在其他任何请求之前发送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,并使用有效负载触发初始请求.
I'm using Laravel passport for API authentication, it works perfectly when I use it with one DB, but gives 401
when using multiple databases,
What I'm doing:
- I have a multi-tenant DB, master DB have users, roles and all OAuth tables.
- When I create a user with admin role it will create new DB with admin name, it will create sub DB with users, roles and all OAuth table.
oauth_clients
of sub DB will copy Password Grant Token and Personal Access Token from master DB and insert in sub DB, and also insertclient_id
inoauth_personal_access_clients
. I'm doing all the procedures which
passport:install
command does. (If I'm not missing something).When I login with credentials from master DB it works perfectly, the real problem starts when I login with credentials from sub-database, I can get sub DB from a param
client_code
which I input withemail
,password
while login.It allows me login from sub DB but I get
401 Unauthenticated
error, get Access token while login and I passAuthentication
Header withBearer
on every request after login fromAngular
front.Don't know what I'm missing here.
DBConnection Middleware
DBConnection middleware sets connection on every request after login,
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
sets default DB in database.php
dynamically, for that, I'm calling setDB
method created on 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);
}
Is it possible to use passport
with 2 different DB for same code?
Laravel 5.4
Passport 4.0
Angular 4.4
in front-end
This is CORS issue. OPTIONS request does not deliver Authorization headers.
If the origin is different from the host, browser going to send OPTIONS before any other request.
Laravel going to answer with the status 401 if CORS middleware is not set up.
So with RESTful architecture, if the client app host is different from the API's host you have to use CORS middleware.
You may use this one: barryvdh/laravel-cors
$ composer require barryvdh/laravel-cors
Example:
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');
});
If CORS middleware works properly a browser shall receive status 200 on the OPTIONS request and fire the initial request with a payload.
这篇关于Laravel护照给401未经验证的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!