Laravel护照给出了401 Unauthenticated错误

时间:2017-12-01 13:40:01

标签: php laravel laravel-passport

我使用Laravel passport进行API身份验证,当我将其与一个数据库一起使用时,它可以正常工作,但在使用多个数据库时会提供401

我在做什么:

  • 我有一个多租户数据库,主数据库有用户,角色和所有OAuth表。
  • 当我创建具有管理员角色的用户时,它将创建具有管理员名称的新数据库,它将创建包含用户,角色和所有OAuth表的子数据库。子数据库的oauth_clients将从主数据库复制密码授予令牌和个人访问令牌并插入子数据库,并在client_id中插入oauth_personal_access_clients
  • 我正在执行passport:install命令执行的所有过程。 (如果我没有遗漏某些东西)。

  • 当我使用来自主数据库的凭据登录时,它运行正常,当我使用子数据库中的凭据登录时,真正的问题就开始了,我可以从我输入client_code的参数email获取子数据库登录时{1}},password

  • 它允许我从子数据库登录但是我得到401 Unauthenticated错误,登录时获取访问令牌,我从{{}登录后,在每个请求上通过Authentication标题Bearer {1}}前面。

  • 不知道我在这里失踪了什么。

DBConnection中间件

DBConnection中间件在登录后为每个请求设置连接,

Angular

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上创建的setDB方法

setDB Controller.php

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个不同的数据库一起使用?

passport Laravel 5.4 前端Passport 4.0

2 个答案:

答案 0 :(得分:0)

回答你的问题:是的,你可以!

在我们的中间件中,我们会这样做:

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

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

我觉得你的search_path没有正确设置。这可以解释为什么你得到 401 。因为Laravel Passport正在错误的数据库中搜索,因为它无法在用户表中找到正确的令牌。

来自PostgreSQL文档(https://www.postgresql.org/docs/9.1/static/runtime-config-client.html):

  

search_path(string)

     

此变量指定在未指定架构的简单名称引用对象(表,数据类型,函数等)时搜索架构的顺序。当在不同模式中存在具有相同名称的对象时,将使用在搜索路径中首先找到的对象。不能在搜索路径中的任何模式中的对象只能通过使用限定(虚线)名称指定其包含模式来引用。

答案 1 :(得分:0)

这是CORS问题。 OPTIONS请求不提供授权标头。

如果原点与主机不同,浏览器将在任何其他请求之前发送OPTIONS。

如果没有设置CORS中间件,Laravel会回复状态401。

因此,使用RESTful架构,如果客户端应用程序主机与API的主机不同,则必须使用CORS中间件。

你可以使用这个: barryvdh/laravel-cors

$ composer require barryvdh/laravel-cors

示例:

应用\ 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并使用有效负载触发初始请求。