[英]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.