我正在使用两个应用程序:accounts.domain.com
(Laravel 应用程序)和dash.domain.com
(不是 laravel,而是 php)。我希望 dash
用户通过 accounts
登录来使用该应用,所以我想我可以使用 OAuth 来实现这一点。
我安装了 Laravel Passport,在获取授权码时一切正常:
$query = http_build_query([
'client_id' => $clientId,
'redirect_uri' => $redirectUri,
'response_type' => 'code',
'scope' => '*',
'state' => $state,
]);
return redirect('https://accounts.domain.com/oauth/authorize?'.$query);
但后来我尝试获取访问 token :
$response = $http->post('https://accounts.domain.com/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'redirect_uri' => $redirectUri,
'code' => $code,
],
]);
我得到了这个错误:
{
"error": "invalid_client",
"error_description": "Client authentication failed",
"message": "Client authentication failed"
}
所以我用谷歌搜索了这个错误,我发现我的凭据可能有错误,所以我检查了它们,尝试重新创建它们,但什么也没有。
最后我到达了这个文件vendor/laravel/passport/src/Bridge/ClientRepository.php
,我在handlesGrant
方法中发现了一些非常有趣的东西,该方法用于验证客户端:
protected function handlesGrant($record, $grantType)
{
// ...
switch ($grantType) {
case 'authorization_code':
return ! $record->firstParty();
// ...
default:
return true;
}
}
我改变了这一行
return ! $record->firstParty();
对此:
return $record->firstParty();
一切顺利。因此,我可以看到,使用 'grant_type' => 'authorization_code'
仅对第三方客户端有效。
我的问题是:为什么第一方客户端不能使用 'authorization_code'
作为授权类型?如果可以的话,“如何在不更改 Laravel Passport 文件的情况下实现这一点?”
最佳答案
我偶然发现了同样的问题,不知道为什么这是默认行为。您可以轻松扩展 ClientRepository 并将其重新绑定(bind)到服务容器:
- 创建文件 app\Passport\ClientRepository.php 并放入以下内容:
<?php
namespace App\Passport;
use Laravel\Passport\Bridge\ClientRepository as BaseClientRepository;
class ClientRepository extends BaseClientRepository
{
/**
* Determine if the given client can handle the given grant type.
*
* @param \Laravel\Passport\Client $record
* @param string $grantType
* @return bool
*/
protected function handlesGrant($record, $grantType)
{
if (is_array($record->grant_types) && ! in_array($grantType, $record->grant_types)) {
return false;
}
switch ($grantType) {
case 'personal_access':
return $record->personal_access_client && $record->confidential();
case 'password':
return $record->password_client;
case 'client_credentials':
return $record->confidential();
default:
return true;
}
}
}
- 注册您的 ClientRepository,将其重新绑定(bind)到服务容器:
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Passport\ClientRepository;
class AuthServiceProvider extends ServiceProvider
{
// Other code
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->bindClientRepository();
}
/**
* Register the client repository.
*
* @return void
*/
protected function bindClientRepository()
{
$this->app->bind(\Laravel\Passport\Bridge\ClientRepository::class, ClientRepository::class);
}
}
关于laravel - 为什么第一方客户端无法处理 Laravel Passport 上的 'authorization_code' 授权类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64920363/