Laravel Passport给出401个未经身份验证的错误



我正在使用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);
    }

DBConnectiondatabase.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个状态,并用有效载荷发射初始请求。

最新更新