使用相同的密钥获取不同的 JWT 令牌
Getting different JWT tokens with the same key
我是 JWT 令牌的新手,我正在尝试从 jwt 令牌获取信息。问题是当我是生成令牌的人时没有问题,但是由于某种原因,当我使用完全相同的信息在 JWT.io 生成令牌时,令牌是不同的,因此,验证失败。我想问题可能出在我使用的密钥上,因为当使用像“HELLO”这样的简单密钥时,这种差异不会发生。这是我的代码:
<?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);
}
}
你的直觉很好。通过检查签名来验证令牌的完整性。令牌由发行方签名。您可以使用不同的算法来签署这些令牌。正如@jps 指出的那样,您可以拥有对称和非对称签名。在对称签名中,相同的密钥用于签名和验证密钥。 HS256
是一种对称签名算法。您可以使用证书来做到这一点(就像在您的代码中一样),但我认为这有点矫枉过正。无论如何,如果您希望在 JWT.io 处生成的密钥在您的代码中有效,您必须将私钥粘贴到 JWT.io 中,以便它可以用于签名。然后令牌应该在您的代码中有效。这就是当您使用简单的字符串作为键时它起作用的原因。
您在代码中生成的令牌和在 JWT.io 中生成的令牌最终可能看起来有些不同。也就是说,它们都是长字符串,三部分由点分隔,但字符串不必相等。这并不意味着这是一个不同的令牌。编码的 JWT 可能会有所不同,具体取决于您是否在输入中使用了换行符,或者您使用了多少空格。尽管经过编码的最终 JWT 可能看起来不同,但这些标记仍然具有相同的值。如果你解码它们,你会得到相同的 JSON,可能格式略有不同。
至于对称算法的使用,通常使用非对称签名会更好,所以如果您可以使用该选项,我绝对会推荐它。另外,看看 PHP 的一些库来发布和验证 JWT,除非你编写代码来了解更多关于 JWT 本身的信息。您可以在 JWT.io.
上找到图书馆列表
如果您计划使用 JWT 保护 API,请查看我写的这篇 security best practices 文章,了解 JWT 的注意事项。
我是 JWT 令牌的新手,我正在尝试从 jwt 令牌获取信息。问题是当我是生成令牌的人时没有问题,但是由于某种原因,当我使用完全相同的信息在 JWT.io 生成令牌时,令牌是不同的,因此,验证失败。我想问题可能出在我使用的密钥上,因为当使用像“HELLO”这样的简单密钥时,这种差异不会发生。这是我的代码:
<?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);
}
}
你的直觉很好。通过检查签名来验证令牌的完整性。令牌由发行方签名。您可以使用不同的算法来签署这些令牌。正如@jps 指出的那样,您可以拥有对称和非对称签名。在对称签名中,相同的密钥用于签名和验证密钥。 HS256
是一种对称签名算法。您可以使用证书来做到这一点(就像在您的代码中一样),但我认为这有点矫枉过正。无论如何,如果您希望在 JWT.io 处生成的密钥在您的代码中有效,您必须将私钥粘贴到 JWT.io 中,以便它可以用于签名。然后令牌应该在您的代码中有效。这就是当您使用简单的字符串作为键时它起作用的原因。
您在代码中生成的令牌和在 JWT.io 中生成的令牌最终可能看起来有些不同。也就是说,它们都是长字符串,三部分由点分隔,但字符串不必相等。这并不意味着这是一个不同的令牌。编码的 JWT 可能会有所不同,具体取决于您是否在输入中使用了换行符,或者您使用了多少空格。尽管经过编码的最终 JWT 可能看起来不同,但这些标记仍然具有相同的值。如果你解码它们,你会得到相同的 JSON,可能格式略有不同。
至于对称算法的使用,通常使用非对称签名会更好,所以如果您可以使用该选项,我绝对会推荐它。另外,看看 PHP 的一些库来发布和验证 JWT,除非你编写代码来了解更多关于 JWT 本身的信息。您可以在 JWT.io.
上找到图书馆列表如果您计划使用 JWT 保护 API,请查看我写的这篇 security best practices 文章,了解 JWT 的注意事项。