Docusign PHP 在尝试获取令牌(JWT 身份验证)时得到 "invalid_grant: unsupported_grant_type"
Docusign PHP getting "invalid_grant: unsupported_grant_type" when trying to get token (JWT auth)
我正在尝试使用 Docusign JWT 身份验证获取访问令牌,但我总是得到:
{"error":"invalid_grant","error_description":"unsupported_grant_type"}
我仔细检查了所有数据(集成密钥、api 用户名等),它们都很好。
我遵循了 Docusign 指南中的所有步骤。
我唯一不能 100% 确定的部分是何时生成 JWT 令牌的签名。
文档说:
The first two parts of the JWT are signed with your application's private key (using the RSA SHA-256 digital signature algorithm) as shown in the diagram.
这就是我生成签名的方式:
$header = [
'typ' => 'JWT',
'alg' => 'RS256'
];
$body = [
'iss' => getenv('INTEGRATION_KEY'),
'sub' => getenv('API_USERNAME'),
'iat' => time(),
'exp' => time() + 3600,
'aud' => str_replace('https://', '', getenv('AUTH_URL')),
'scope' => 'signature impersonation'
];
$signature = JWT::encode($body, file_get_contents(env('PRIVATE_KEY')), 'RS256');
$header = $this->base64url_encode(json_encode($header));
$body = $this->base64url_encode(json_encode($body));
$jwt = $header . '.' . $body . '.' . $signature;
对吗?
如果不是,并且由于 JWT::encode 需要一个数组作为第一个参数,我应该怎么做才能让它工作?
这是我请求访问令牌的方式:
return Http::withHeaders(
[
'Content-Type' => 'application/x-www-form-urlencoded'
]
)->post(
getenv('AUTH_URL') . '/oauth/token',
[
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
]
);
谢谢!
创建正确的 JWT 令牌很困难。我建议您要么使用 requestJWTUserToken from the PHP SDK or review its source 看看它是如何发出 OAuth 请求的。
显然 Firebase JWT 编码方法没有以正确的方式编码字符串。
我用过这个:
$header = $this->base64url_encode(json_encode($header));
$body = $this->base64url_encode(json_encode($body));
openssl_sign(
$header.".".$body,
$signature,
file_get_contents(env('PRIVATE_KEY_PATH')),
"sha256WithRSAEncryption"
);
成功了。
请确保您在请求同意和请求 jwt 令牌时使用相同的范围。
感谢大家的帮助。
我在使用 Laravel 6 的应用程序中遇到了同样的问题,我设法解决了如下问题:
// the Header will not be needed as it is automatically generated
$header = [
'typ' => 'JWT',
'alg' => 'RS256'
];
$body = [
'iss' => getenv('INTEGRATION_KEY'),
'sub' => getenv('API_USERNAME'),
'iat' => time(),
'exp' => time() + 3600,
'aud' => str_replace('https://', '', getenv('AUTH_URL')),
'scope' =>'signature impersonation'
];
/**
* Note that when creating the JWT, only the $body is provided,
* as the function already performs the necessary concatenations.
* in your code you put it like this:
* $jwt = $header . '.' . $body . '.' . $signature;
* which generates a hash that cannot be validated,
*/
// create the JWT
$jwt = JWT::encode($body , $privateKey, 'RS256');
// make the request
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', getenv('AUTH_URL').'/oauth/token',['query' =>[
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt,
]
]);
echo '<pre>';
print_r($response);
echo '</pre>';
我正在尝试使用 Docusign JWT 身份验证获取访问令牌,但我总是得到:
{"error":"invalid_grant","error_description":"unsupported_grant_type"}
我仔细检查了所有数据(集成密钥、api 用户名等),它们都很好。 我遵循了 Docusign 指南中的所有步骤。
我唯一不能 100% 确定的部分是何时生成 JWT 令牌的签名。 文档说:
The first two parts of the JWT are signed with your application's private key (using the RSA SHA-256 digital signature algorithm) as shown in the diagram.
这就是我生成签名的方式:
$header = [
'typ' => 'JWT',
'alg' => 'RS256'
];
$body = [
'iss' => getenv('INTEGRATION_KEY'),
'sub' => getenv('API_USERNAME'),
'iat' => time(),
'exp' => time() + 3600,
'aud' => str_replace('https://', '', getenv('AUTH_URL')),
'scope' => 'signature impersonation'
];
$signature = JWT::encode($body, file_get_contents(env('PRIVATE_KEY')), 'RS256');
$header = $this->base64url_encode(json_encode($header));
$body = $this->base64url_encode(json_encode($body));
$jwt = $header . '.' . $body . '.' . $signature;
对吗? 如果不是,并且由于 JWT::encode 需要一个数组作为第一个参数,我应该怎么做才能让它工作?
这是我请求访问令牌的方式:
return Http::withHeaders(
[
'Content-Type' => 'application/x-www-form-urlencoded'
]
)->post(
getenv('AUTH_URL') . '/oauth/token',
[
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
]
);
谢谢!
创建正确的 JWT 令牌很困难。我建议您要么使用 requestJWTUserToken from the PHP SDK or review its source 看看它是如何发出 OAuth 请求的。
显然 Firebase JWT 编码方法没有以正确的方式编码字符串。
我用过这个:
$header = $this->base64url_encode(json_encode($header));
$body = $this->base64url_encode(json_encode($body));
openssl_sign(
$header.".".$body,
$signature,
file_get_contents(env('PRIVATE_KEY_PATH')),
"sha256WithRSAEncryption"
);
成功了。
请确保您在请求同意和请求 jwt 令牌时使用相同的范围。
感谢大家的帮助。
我在使用 Laravel 6 的应用程序中遇到了同样的问题,我设法解决了如下问题:
// the Header will not be needed as it is automatically generated
$header = [
'typ' => 'JWT',
'alg' => 'RS256'
];
$body = [
'iss' => getenv('INTEGRATION_KEY'),
'sub' => getenv('API_USERNAME'),
'iat' => time(),
'exp' => time() + 3600,
'aud' => str_replace('https://', '', getenv('AUTH_URL')),
'scope' =>'signature impersonation'
];
/**
* Note that when creating the JWT, only the $body is provided,
* as the function already performs the necessary concatenations.
* in your code you put it like this:
* $jwt = $header . '.' . $body . '.' . $signature;
* which generates a hash that cannot be validated,
*/
// create the JWT
$jwt = JWT::encode($body , $privateKey, 'RS256');
// make the request
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', getenv('AUTH_URL').'/oauth/token',['query' =>[
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt,
]
]);
echo '<pre>';
print_r($response);
echo '</pre>';