Laravel dingo/api - 使用 Passport (L6) 的内部路由
Laravel dingo/api - Using internal routes with Passport (L6)
我看到很多人对此有类似的问题,但没有最终解决方案。我一直在努力让它工作大约 24 小时,但仍然没有成功!
目标
- 使用 Laravel 6 和 Dingo API
构建和 API
- 能够在外部使用 API,使用 Passport oAuth 进行身份验证。
- 能够通过 ajax 在内部使用 API,使用护照自我验证功能。
- 能够使用 dingo 的自我消耗方法在内部消耗 API,PHP。
到目前为止我发现了什么
授权提供商订单
我见过的大多数解决方案都建议同时设置护照身份验证和野狗。这是 auth:api
(护照)和 api.auth
(野狗)。
// API route middleware
$api->group(['middleware' => 'auth:api', 'api.auth'], function (Router $api) {
...
这里的api.auth
实际上是在laravel中设置的自定义auth provider,配置为dingo,桥接passport逻辑到dingo。
// Auth provider
class DingoPassportAuthProvider extends Authorization
{
protected $guard;
public function __construct(AuthManager $auth)
{
dump('DingoPassportAuthProvider Instantiated');
$this->guard = $auth->guard('api');
}
public function authenticate(Request $request, Route $route)
{
if ($this->guard->check()) {
return $this->guard->user();
}
throw new UnauthorizedHttpException('Not authenticated via Passport.');
}
public function getAuthorizationMethod()
{
return 'Bearer';
}
}
// Configured in dingo (Api.php)
'auth' => [
'passport' => \App\Providers\DingoPassportAuthProvider::class,
],
如果我们将 dingo API 提供程序放在中间件堆栈的第一位,我们将得到:
内部 API 请求工作如果您使用 be() 方法指定调用的用户:$this->api->be($request->user())->get('/api/profile')
外部 API 请求和内部 AJAX 请求正确验证并且用户是 return 来自自定义野狗身份验证提供程序的,但是,出于某种原因你然后无法从 API 控制器中访问该用户:$user = $request->user(); // null
如果我们将 Passport API 提供程序放在中间件堆栈的第一位,我们将得到:
内部 API 请求根本不起作用(401 总是 returned)
外部 API 请求和内部 AJAX 请求按预期工作。
不再调用 dingo 护照提供程序上的 authenticate
方法。我认为这可能与内部调用的 401 returned 有关。
我认为正确的做法是先进行护照认证。这样,我们在调用 dingo 身份验证之前对用户进行身份验证,导致两件事:
Passport 按预期在本机工作。
Dingo 内部 API 调用现在应该只能用 $this->api->get('/api/profile')
调用(省略用 be()
定义用户),但这不起作用.
目前我有以前的配置。 Passport 按预期用于外部和 ajax 调用,但内部 dingo 调用总是 return 401.
我检查了一些样板模板,它们似乎没有任何不同之处。我想知道 L6 中是否发生了一些变化来解释为什么内部请求不起作用。
我现在找到了一个变通方法,大部分都用到了...
在自定义 dingo 身份验证提供程序中:
class DingoPassportAuthProvider extends Authorization
{
public function authenticate(Request $request, Route $route)
{
if (Auth::guard('web')->check()) {
return Auth::guard('web')->user();
}
if (Auth::guard('api')->check()) {
$user = Auth::guard('api')->user();
Passport::actingAs($user);
return $user;
}
throw new UnauthorizedHttpException('Not authenticated via Passport.');
}
public function getAuthorizationMethod()
{
return 'Bearer';
}
}
现在检查请求是否来自网络防护(内部请求)或 api 防护(外部或 ajax 请求)和 returns 正确的用户。
对于 api 守卫,似乎存在用户已通过身份验证但实际上在控制器中不可用的问题。为了解决这个问题,我添加了 Passport::actingAs($user)
。这可能不是最佳做法,但警卫现在正在按照他们应该的方式行事,就像我所有的不同场景一样。
然后在API路由中间件中,我们只指定custom dingo provider
// API route middleware
$api->group(['middleware' => 'api.auth'], function (Router $api) {
...
有一点需要注意,澳洲野狗 be()
方法并没有像预期的那样工作。相反,您需要像在一般 laravel 应用程序中那样切换用户。
\Auth::loginUsingId(2);
$user = $this->api->get('/api/profile');
我看到很多人对此有类似的问题,但没有最终解决方案。我一直在努力让它工作大约 24 小时,但仍然没有成功!
目标
- 使用 Laravel 6 和 Dingo API 构建和 API
- 能够在外部使用 API,使用 Passport oAuth 进行身份验证。
- 能够通过 ajax 在内部使用 API,使用护照自我验证功能。
- 能够使用 dingo 的自我消耗方法在内部消耗 API,PHP。
到目前为止我发现了什么
授权提供商订单
我见过的大多数解决方案都建议同时设置护照身份验证和野狗。这是 auth:api
(护照)和 api.auth
(野狗)。
// API route middleware
$api->group(['middleware' => 'auth:api', 'api.auth'], function (Router $api) {
...
这里的api.auth
实际上是在laravel中设置的自定义auth provider,配置为dingo,桥接passport逻辑到dingo。
// Auth provider
class DingoPassportAuthProvider extends Authorization
{
protected $guard;
public function __construct(AuthManager $auth)
{
dump('DingoPassportAuthProvider Instantiated');
$this->guard = $auth->guard('api');
}
public function authenticate(Request $request, Route $route)
{
if ($this->guard->check()) {
return $this->guard->user();
}
throw new UnauthorizedHttpException('Not authenticated via Passport.');
}
public function getAuthorizationMethod()
{
return 'Bearer';
}
}
// Configured in dingo (Api.php)
'auth' => [
'passport' => \App\Providers\DingoPassportAuthProvider::class,
],
如果我们将 dingo API 提供程序放在中间件堆栈的第一位,我们将得到:
内部 API 请求工作如果您使用 be() 方法指定调用的用户:
$this->api->be($request->user())->get('/api/profile')
外部 API 请求和内部 AJAX 请求正确验证并且用户是 return 来自自定义野狗身份验证提供程序的,但是,出于某种原因你然后无法从 API 控制器中访问该用户:
$user = $request->user(); // null
如果我们将 Passport API 提供程序放在中间件堆栈的第一位,我们将得到:
内部 API 请求根本不起作用(401 总是 returned)
外部 API 请求和内部 AJAX 请求按预期工作。
不再调用 dingo 护照提供程序上的
authenticate
方法。我认为这可能与内部调用的 401 returned 有关。
我认为正确的做法是先进行护照认证。这样,我们在调用 dingo 身份验证之前对用户进行身份验证,导致两件事:
Passport 按预期在本机工作。
Dingo 内部 API 调用现在应该只能用
$this->api->get('/api/profile')
调用(省略用be()
定义用户),但这不起作用.
目前我有以前的配置。 Passport 按预期用于外部和 ajax 调用,但内部 dingo 调用总是 return 401.
我检查了一些样板模板,它们似乎没有任何不同之处。我想知道 L6 中是否发生了一些变化来解释为什么内部请求不起作用。
我现在找到了一个变通方法,大部分都用到了...
在自定义 dingo 身份验证提供程序中:
class DingoPassportAuthProvider extends Authorization
{
public function authenticate(Request $request, Route $route)
{
if (Auth::guard('web')->check()) {
return Auth::guard('web')->user();
}
if (Auth::guard('api')->check()) {
$user = Auth::guard('api')->user();
Passport::actingAs($user);
return $user;
}
throw new UnauthorizedHttpException('Not authenticated via Passport.');
}
public function getAuthorizationMethod()
{
return 'Bearer';
}
}
现在检查请求是否来自网络防护(内部请求)或 api 防护(外部或 ajax 请求)和 returns 正确的用户。
对于 api 守卫,似乎存在用户已通过身份验证但实际上在控制器中不可用的问题。为了解决这个问题,我添加了 Passport::actingAs($user)
。这可能不是最佳做法,但警卫现在正在按照他们应该的方式行事,就像我所有的不同场景一样。
然后在API路由中间件中,我们只指定custom dingo provider
// API route middleware
$api->group(['middleware' => 'api.auth'], function (Router $api) {
...
有一点需要注意,澳洲野狗 be()
方法并没有像预期的那样工作。相反,您需要像在一般 laravel 应用程序中那样切换用户。
\Auth::loginUsingId(2);
$user = $this->api->get('/api/profile');