Laravel 护照出现 401 Unauthenticated 错误
Posted
技术标签:
【中文标题】Laravel 护照出现 401 Unauthenticated 错误【英文标题】:Laravel passport gives 401 Unauthenticated error 【发布时间】:2018-05-15 15:14:15 【问题描述】:我正在使用 Laravel 护照进行 API 身份验证,当我将它与一个数据库一起使用时它可以完美运行,但在使用多个数据库时会给出 401
,
我在做什么:
我有一个多租户数据库,主数据库有用户、角色和所有 OAuth 表。 当我创建一个具有管理员角色的用户时,它将创建具有管理员名称的新数据库,它将创建具有用户、角色和所有 OAuth 表的子数据库。子数据库的oauth_clients
将从主数据库复制密码授予令牌和个人访问令牌并插入子数据库,并在oauth_personal_access_clients
中插入client_id
。
我正在执行passport:install
命令执行的所有程序。 (如果我没有遗漏什么)。
当我使用主数据库中的凭据登录时,它运行良好,真正的问题是当我使用子数据库中的凭据登录时,我可以从参数client_code
获取子数据库,我使用email
输入,password
登录时。
它允许我从子数据库登录,但我收到 401 Unauthenticated
错误,登录时获取访问令牌,并且我在从 Angular
前面登录后的每个请求上传递带有 Bearer
的 Authentication
标头。
不知道我在这里缺少什么。
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 个不同的数据库一起用于相同的代码?
Laravel 5.4
Passport 4.0
Angular 4.4
在前端
【问题讨论】:
你如何在数据库之间切换以及你的标题里面到底有什么?这听起来像是其中之一的问题。 @tprj29 我创建了一个设置数据库配置的中间件,我在路由参数中传递了一个数据库名称,我认为它没有问题,因为登录完美,但登录后出现问题,它开始给出 401 错误,在前面使用 Angular 4 这听起来确实像一个标题问题,因为标题Authentication
只有在登录后才需要。而且由于登录和获取不记名令牌可以根据您的需要完美运行。你能告诉我们你的标题Authentication
有什么价值吗?
@tprj29 授权与登录传递的相同
代码会有所帮助,因为如果没有 anny 代码片段,很难看出哪里出错了
【参考方案1】:
回答你的问题:是的,你可以!
在我们的中间件中,我们这样做:
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):
搜索路径(字符串)
此变量指定在未指定架构的简单名称引用对象(表、数据类型、函数等)时搜索架构的顺序。当不同模式中存在同名对象时,使用在搜索路径中首先找到的对象。不在搜索路径中的任何架构中的对象只能通过使用限定(点分)名称指定其包含架构来引用。
【讨论】:
我没有使用PostgreSQL
,我使用的是mysql
在您处理查询的模型中,您可以记录使用的连接吗?我认为模型内部没有正确管理连接。
如果我不使用passport
连接完美【参考方案2】:
这是 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 并使用有效负载触发初始请求。
【讨论】:
他没有发送OPTIONS
请求 - 他的中间件正在检查方法 other 而不是 OPTIONS
以上是关于Laravel 护照出现 401 Unauthenticated 错误的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 护照 oauth 路线总是返回 401 未经授权
在 Laravel 护照、vueJS 和 Axios 中获得未经授权的 401