Laravel 5.4 OAuth与Dingo内部请求

Squ*_*gs. 10 php oauth laravel laravel-5 dingo-api

我正在使用Laravel 5.4和Dingo API,我正在尝试使用Laravel的OAuth 2.0(Passport)来处理Internal Dingo请求.以前,我使用的是JWT,但现在我想使用OAuth.这是我之前的调度程序代码,它传递了所需的令牌以对内部请求执行身份验证.

public function getDispatcher()
{
    $token = JWTAuth::fromUser(Auth::user());
    return $this->api->header('Authorization','Bearer'.$token)->be(Auth::user());
}
Run Code Online (Sandbox Code Playgroud)

现在我正在使用OAuth进行身份验证,我的JavaScript代码只需在JavaScript中使用此方法传递cookie即可获得身份验证,这非常有效.

现在我需要修改getDispatcher()方法以在Dingo中的"内部请求"上获取OAuth令牌.有没有人有关于如何做到这一点的任何提示?从理论上讲,我可以为每个用户创建一个个人访问令牌,但这似乎只是内部请求的过度杀伤.任何建议或方法表示赞赏.如何在不通过完整OAuth流程的情况下获取OAuth令牌,或者如何仅为内部请求关闭身份验证.

根据以下答案更新:

'api.auth'自己在路线上(只是Dingo)并且内部请求有效.auth:api(Passport)+ api.auth我得到了内部请求不允许的方法,它以JSON的形式返回.尝试调用内部POST请求时出现{"message":"405 Method Not Allowed"}.(当尝试POST到这些路由时,看起来像301重定向到登录页面,反过来导致API路径以某种方式变成GET,从而抛出405错误).

通过Postman的API请求以反向容量工作.两个活动时都找不到用户(['middleware'=> ['auth:api','api.auth'])当(auth:api只是Passport)激活时它工作正常.

Cy *_*nol 7

如果我正确地阅读了这个问题,看起来我们正在尝试同时使用两个身份验证提供程序 - Dingo和Passport.如果我误解了,请纠正我,但似乎我们实际上并不需要在这个项目中同时使用这两个.对于大多数应用程序,我们可以使用Passport执行身份验证,并将结果简单地传递给Dingo.

我们通过创建自定义身份验证提供程序来实现此目的,该提供程序将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.');
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,上面显示的Dingo auth提供程序只是挂钩到Laravel auth系统,以便User在进行身份验证时转发.'api'构造函数中指定的防护应该与为Passport配置的防护匹配(我们通常在config/auth.php中'api''guards'数组添加一个条目):

'guards' => [
    ...
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],
Run Code Online (Sandbox Code Playgroud)

然后,我们需要在config/api.php中使用Dingo注册自定义提供程序:

'auth' => 
    'passport' => App\Providers\PassportDingoAuthProvider::class
]
Run Code Online (Sandbox Code Playgroud)

现在我们可以声明使用Passport auth middleware(auth:api)和Dingo auth middleware(api.auth)的受保护路由:

$api->get('endpoint', function () { ... })->middleware('auth:api', 'api.auth');
Run Code Online (Sandbox Code Playgroud)

我们可以在app/Http/Kernel.php中创建一个中间件组,如果需要,可以将它们组合在一起:

protected $middlewareGroups = [
    ...
    'auth:api-combined' => [
        'auth:api', // Passport
        'api.auth'  // Dingo
    ]
];
Run Code Online (Sandbox Code Playgroud)

当应用程序需要调用内部API时,客户端应该已经过身份验证,因为典型的Laravel应用程序处理中间件堆栈中的身份验证.如您所知,User如果需要,我们可以简单地将经过身份验证的端口传递给Dingo端点:

return $this->api->be(auth()->user())->get('endpoint');
Run Code Online (Sandbox Code Playgroud)

...但是上面显示的auth提供程序不需要这样做.Dingo将从Passport的auth guard中解析经过身份验证的用户.

这是一个结合了这些概念的示例项目.

现在我正在使用OAuth进行身份验证,我的Javascript代码只需通过在Javascript中使用此方法传递cookie来设置身份验证...我需要修改getDispatcher方法以在"内部请求"中获取OAuth令牌巴丁格.

当我们使用CreateFreshApiToken中间件时,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());
Run Code Online (Sandbox Code Playgroud)

我们可以看到这不是标准的OAuth访问令牌 - Passport仅将这些用于Web请求.或者,我们可以从JavaScript传回的cookie中获取此值:

$token = request()->cookie(Passport::cookie());
Run Code Online (Sandbox Code Playgroud)

但是,如果我们将Dingo与Passport集成在一起,我们就不需要这个令牌.