繁体   English   中英

Laravel 5.4 OAuth与Dingo内部请求

[英]Laravel 5.4 OAuth with Dingo internal requests

我正在将Laravel 5.4与Dingo API一起使用,并且试图将Laravel的OAuth 2.0(护照)与内部Dingo请求一起使用。 以前,我使用的是JWT,但现在我希望使用OAuth。 这是我以前的调度程序代码,传递所需的令牌以对内部请求执行身份验证。

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

现在,我使用OAuth进行身份验证,我的JavaScript代码通过使用 JavaScript中的此方法传递cookie来设法获得身份验证,效果很好。

现在,我需要修改getDispatcher()方法,以在Dingo中的“内部请求”上获取OAuth令牌。 有人对如何执行此操作有任何提示吗? 从理论上讲,我可以为每个用户创建一个个人访问令牌,但这似乎对内部请求来说太过分了。 任何建议或方法表示赞赏。 如何不经过完整的OAuth流程即可获取OAuth令牌,或者如何仅针对内部请求关闭身份验证。

根据以下答案进行更新:

“ api.auth”在路由上(仅是Dingo)就可以使用,并且内部请求有效。 auth:api(Passport)+ api.auth,我得到内部请求不允许的方法,该方法以JSON形式返回。 现在,当尝试调用内部POST请求时,出现{“ message”:“ 405方法不允许”}。 (当尝试将POST路由到这些路由时,似乎发生了301重定向到登录页面的情况,从而导致API路径以某种方式变为GET,从而引发405错误)。

通过邮递员的API请求以相反的方式工作。 当(auth:api仅Passport)都激活时,两个都激活(['middleware'=> ['auth:api','api.auth'])时找不到用户。

如果我正确阅读了该问题,则似乎我们正在尝试同时使用两个身份验证提供程序-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.');
    }
}

如我们所见,上面显示的Dingo身份验证提供程序仅挂接到Laravel身份验证系统,以在身份验证时转发User ): 在构造函数中指定的'api'防护应与为Passport配置的防护相匹配(我们通常在'guards'数组中添加'api'条目):

'guards' => [
    ...
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

: 然后,我们需要在向Dingo注册自定义提供程序:

'auth' => 
    'passport' => App\Providers\PassportDingoAuthProvider::class
]

现在,我们可以声明使用Passport身份验证中间件( auth:api )和Dingo身份验证中间件( api.auth )的受保护路由:

$api->get('endpoint', function () { ... })->middleware('auth:api', 'api.auth');

that combines these if desired: 我们可以在中创建一个中间件组 ,如果需要,可以将它们组合在一起:

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的身份验证保护功能解析经过身份验证的用户。

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

既然我正在使用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());

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

$token = request()->cookie(Passport::cookie());

但是,如果如上所述将Dingo与Passport集成,则不需要此令牌。

暂无
暂无

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

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