如果我没看错问题,看起来我们正在尝试同时使用两个身份验证提供程序——Dingo's 和 Passport。如果我误解了,请纠正我,但似乎我们实际上不需要在这个项目中同时使用两者。对于大多数应用程序,我们可以使用 Passport 执行身份验证,并将结果简单地传递给 Dingo。
我们通过创建一个custom authentication provider 来实现这一点,它将 Dingo 与 Passport 执行的身份验证联系起来:
use Dingo\Api\Contract\Auth\Provider;
use Illuminate\Auth\AuthManager;
...
class PassportDingoAuthProvider implements Provider
{
protected $guard;
public function __construct(AuthManager $auth)
{
$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.');
}
}
如我们所见,上面显示的 Dingo 身份验证提供程序只是挂钩到 Laravel 身份验证系统,以在通过身份验证时转发 User。构造函数中指定的'api' 守卫应该与configured for Passport 守卫相匹配(我们通常在config/auth.php 中的'guards' 数组中添加一个'api' 条目):
'guards' => [
...
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
然后,我们需要在config/api.php中向Dingo注册自定义提供者:
'auth' =>
'passport' => App\Providers\PassportDingoAuthProvider::class
]
现在我们可以声明使用 Passport 身份验证中间件 (auth:api) 和 Dingo 身份验证中间件 (api.auth) 的受保护路由:
$api->get('endpoint', function () { ... })->middleware('auth:api', 'api.auth');
如果需要,我们可以在 app/Http/Kernel.php 中创建一个 middleware group 来组合这些:
protected $middlewareGroups = [
...
'auth:api-combined' => [
'auth:api', // Passport
'api.auth' // Dingo
]
];
当应用程序需要调用内部 API 时,客户端应该已经通过身份验证,因为典型的 Laravel 应用程序在中间件堆栈中处理身份验证。如您所知,如果需要,我们可以简单地将经过身份验证的 User 传递给 Dingo 端点:
return $this->api->be(auth()->user())->get('endpoint');
...但是对于上面显示的身份验证提供程序,这应该不是必需的。 Dingo 将从 Passport 的 auth guard 中解析出经过身份验证的用户。
a sample project 结合了这些概念。
现在我正在使用 OAuth 进行身份验证,我的 Javascript 代码只需通过在 Javascript 中使用此方法传递一个 cookie 即可获得身份验证...我需要修改 getDispatcher 方法以获取“内部”上的 OAuth 令牌在 Dingo 中请求。
当我们使用CreateFreshApiToken middleware 时,Laravel 会即时生成一个加密的 JWT。我们可以手动创建以下令牌之一:
use Firebase\JWT\JWT; // installed with Passport
...
$token = JWT::encode([
'sub' => auth()->id(),
'csrf' => session()->token(),
'expiry' => Carbon::now()->addMinutes(config('session.lifetime')),
], app('encrypter')->getKey());
我们可以看到这不是标准的 OAuth 访问令牌 - Passport 仅将这些用于 Web 请求。或者,我们可以从 JavaScript 传回的 cookie 中获取这个值:
$token = request()->cookie(Passport::cookie());
但是,如果我们如上所述将 Dingo 与 Passport 集成,则不需要此令牌。