JWT 令牌似乎是正确的,但收到的响应是 401
Posted
技术标签:
【中文标题】JWT 令牌似乎是正确的,但收到的响应是 401【英文标题】:JWT token appears to be correct but response received is 401 【发布时间】:2019-06-05 21:19:50 【问题描述】:我正在尝试使用 JWT Bearer Grant Type 连接到 Docebo API,但遇到了问题:
使用下面的代码,我收到以下响应(即使在 https://jwt.io 验证时我的 $token 似乎是正确的):
stdClass Object ( [name] => Unauthorized [message] => Array ( [0] => Your request was made with invalid credentials. ) [code] => 0 [status] => 401 )
这是用于生成 $token 的代码,以及那个错误 ^
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
function base64url_encode($data)
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
$key = 'example_public_key';
$headers = ['alg'=>'RS256','typ'=>'JWT'];
$headers_encoded = base64url_encode(json_encode($headers));
$today = time();
$tomorrow = time() + (1 * 24 * 60 * 60);
$payload = [
'iss' => 'example_client_id',
'sub' => 'example_user',
'aud' => 'example.docebosaas.com',
'iat' => $today,
'exp' => $tomorrow
];
$payload_encoded = base64url_encode(json_encode($payload));
$signature = hash_hmac('SHA256',"$headers_encoded.$payload_encoded",$key,true);
$signature_encoded = base64url_encode($signature);
$token = "$headers_encoded.$payload_encoded.$signature_encoded";
$curl = curl_init();
$curl_data = array(
'token' => $token
);
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POSTFIELDS => $curl_data,
CURLOPT_URL => 'https://example.docebosaas.com/manage/v1/user'
));
$resp = curl_exec($curl);
curl_close($curl);
$json_obj = json_decode($resp);
print_r($json_obj);
更新:
根据下面的评论,我现在添加了适当的标头,并且不再收到 401。但是,将 CURL 调用更改为以下有一个新错误:
stdClass Object ( [error] => invalid_grant [error_description] => JWT failed signature verification )
这是更新后的 CURL 调用的代码:
$curl = curl_init();
$curl_data = array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'scope' => 'api',
'assertion' => $token
);
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POSTFIELDS => $curl_data,
CURLOPT_URL => 'https://example.docebosaas.com/oauth2/token'
));
$resp = curl_exec($curl);
curl_close($curl);
$json_obj = json_decode($resp);
print_r($json_obj);
【问题讨论】:
【参考方案1】:您的 curl 示例不包含我期望的标题,例如:
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
scope=api
assertion=YOUR_SIGNED_JWT
另外,您可能希望改为调用端点 https://<yoursubdomain.docebosaas.com>/oauth2/token
将您的签名 JWT 转换为普通的不记名令牌。然后就可以使用标准的 Authorization 头了:
Authorization: Bearer YOUR_ACCESS_TOKEN
API General Information
【讨论】:
嗨,约翰 - 感谢您提出这个问题。现在我已经添加了这些标头并更改了端点,我收到了这个错误:stdClass Object ([error] => invalid_grant [error_description] => JWT failed signature verification) 我已经更新了我的原始帖子使用我用于 curl 调用的新代码。 错误消息意味着您的签名不起作用,这可能就像没有使用密钥对的正确部分一样简单。您在代码中提及public
,通常您会使用private
密钥对进行签名。 public
密钥对用于验证签名。
您可以从私钥生成公钥,但不能从公钥生成私钥。私钥实际上包含构成公钥的两个数字。公钥缺少构成私钥的所有其他内容。以上是关于JWT 令牌似乎是正确的,但收到的响应是 401的主要内容,如果未能解决你的问题,请参考以下文章
ASP.Net Core 3 API 总是返回 401- JwtBearer