繁体   English   中英

Laravel dingo/api - 使用带 Passport 的内部路由 (L6)

[英]Laravel dingo/api - Using internal routes with Passport (L6)

我看到很多人对此有类似的问题,但没有最终解决方案。 我一直试图让它工作大约 24 小时,但仍然没有运气!

目标

  1. 使用 Laravel 6 和 Dingo API 构建和 API
  2. 能够在外部使用 API,使用 Passport oAuth 进行身份验证。
  3. 能够使用护照自认证功能通过 ajax 在内部使用 API。
  4. 能够在内部使用 API 和 PHP,使用 dingo 的自消费方法。

到目前为止我发现了什么

身份验证提供程序订单

我见过的大多数解决方案都建议同时设置护照身份验证和野狗。 这是auth:api (护照)和api.auth (野狗)。

// API route middleware
$api->group(['middleware' =>  'auth:api', 'api.auth'], function (Router $api) {
...

这里的api.auth实际上是 laravel 中的自定义身份验证提供程序设置,并配置为 dingo,它将护照逻辑桥接到 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 提供程序首先放在中间件堆栈中,我们会得到:

  • 如果您使用 be() 方法为调用指定用户,则内部 API 请求工作: $this->api->be($request->user())->get('/api/profile')

  • 外部 API 请求和内部 AJAX 请求正确验证,并且用户从自定义 dingo 身份验证提供程序返回,但是,由于某种原因,您无法从 ZDB974238714CA8DE634A7CE1D083A14F 中访问此$user = $request->user(); // null $user = $request->user(); // null

如果我们将 Passport API 提供程序放在中间件堆栈的第一位,我们将得到:

  • 内部 API 请求根本不起作用(总是返回 401)

  • 外部 API 请求和内部 AJAX 请求按预期工作。

  • 不再调用 dingo 护照提供程序上的authenticate方法。 我认为这可能与内部呼叫返回的 401 有关。

我相信正确的方法是将护照认证放在首位。 这样,我们在调用 dingo 身份验证之前对用户进行身份验证,导致两件事:

  1. Passport 按预期在本地工作。

  2. Dingo 内部 API 调用现在应该只能使用$this->api->get('/api/profile')调用(省略使用be()定义用户),但这不起作用。

目前我有以前的配置。 Passport 可按预期用于外部和 ajax 调用,但内部 dingo 调用始终返回 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';
    }
}

现在检查请求是否来自 web 保护(内部请求)或 api 保护(外部或 ajax 请求)并返回正确的用户。

对于 api 防护,似乎存在用户经过身份验证但在控制器中实际上不可用的问题。 为了解决这个问题,我添加了Passport::actingAs($user) 这可能不是最佳实践,但警卫现在正在按照他们应该的方式行事,并且是我所有不同的场景。

然后在API路由中间件中,我们只指定了自定义的dingo provider。

// API route middleware
$api->group(['middleware' => 'api.auth'], function (Router $api) {
...

需要注意的一件事是 dingos be()方法并没有像预期的那样工作。 相反,您需要像在一般 laravel 应用程序中那样切换用户。

\Auth::loginUsingId(2);
$user = $this->api->get('/api/profile');

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM