我对JWT标记不熟悉,我正在尝试从jwt标记中获取信息。问题是,当我生成标记时,我没有遇到问题,但是,由于某种原因,当我在JWT.io处使用完全相同的信息生成标记时,标记是不同的,因此验证失败。我猜问题可能来自于我使用的密钥,当使用像“HELLO”这样的简单键时,这种不一致不会发生。2这是我的代码:
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
use \Firebase\JWT\JWT;
use Cake\ORM\TableRegistry;
class JWTComponent extends Component
{
public function check_token($token){
$decoded = [];
$key = openssl_pkey_get_details(openssl_pkey_get_private('file://'.APP.'private.pem'))['key'];
try {
$decoded = JWT::decode($token, $key, array('HS256'));
$decoded = (array) $decoded;
} catch (Exception $e) {
$decoded = ['error' => $e->getMessage()];
}finally{
return $decoded;
}
}
public function get_token($data) {
$key = openssl_pkey_get_details(openssl_pkey_get_private('file://'.APP.'private.pem'))['key'];
return JWT::encode($data, $key);
}
}
1条答案
按热度按时间wj8zmpe11#
您的直觉是正确的。令牌的完整性是通过检查签名来验证的。令牌是由颁发它们的一方签名的。您可以使用不同的算法来对这些令牌进行签名。正如@jps指出的,您可以有对称和非对称签名。在对称签名中,使用相同的密钥来签名和验证密钥。
HS256
是对称签名算法。您可以使用证书来实现这一点(就像在您的代码中一样),但在我看来,这有点JWT.io。您必须将私钥粘贴到JWT.io中,以便可以使用它进行签名。然后,标记在您的代码中应该是有效的。这就是为什么当你用一个简单的字符串作为键时它能工作的原因。您在代码中生成的标记和在www.example.com中JWT.io最终看起来可能会有些不同。也就是说,它们都是长字符串,由点分隔成三个部分,但字符串不必相等。这并不意味着这是一个不同的标记。编码的JWT可能会有所不同,这取决于您是否在输入中使用了换行符,或者使用了多少个空格。即使编码后的最终JWT看起来不同,这些标记仍然具有相同的值。如果对它们进行解码,将得到相同的JSON,只是格式略有不同。
至于对称算法的使用,通常使用非对称签名更好,所以如果你能使用这个选项,我肯定会推荐它。另外,看看PHP发布和验证JWT的一些库,除非你写代码来了解更多关于JWT本身的信息。你可以在JWT.io上找到库的列表。
如果您计划使用JWT来保护您的API,请阅读我写的这篇security best practices文章,了解JWT的注意事项。