Существует несколько библиотек для реализации JSON Web Tokens (JWT) в PHP, таких как PHP-JWT. Я пишу свой собственный, очень маленький и простой класс, но не могу понять, почему моя подпись не проходит проверку Вот хотя я пытался придерживаться стандарта. Я пытался часами, и я застрял. Пожалуйста помоги!
Мой код прост
//build the headers
$headers = ['alg'=>'HS256','typ'=>'JWT'];
$headers_encoded = base64url_encode(json_encode($headers));
//build the payload
$payload = ['sub'=>'1234567890','name'=>'John Doe', 'admin'=>true];
$payload_encoded = base64url_encode(json_encode($payload));
//build the signature
$key = 'secret';
$signature = hash_hmac('SHA256',"$headers_encoded.$payload_encoded",$key);
//build and return the token
$token = "$headers_encoded.$payload_encoded.$signature";
echo $token;
base64url_encode
функция:
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
Мои заголовки и полезная нагрузка идеально соответствуют проверка сайта JWT по умолчанию, но моя подпись не совпадает, поэтому мой токен помечен как недействительный. Этот стандарт кажется очень простым, так что не так с моей подписью?
Я решил это! Я не понял, что сама подпись должна быть закодирована в base64. Кроме того, мне нужно было установить последний необязательный параметр hash_hmac
функция к $raw_output=true
(увидеть документы. Короче говоря, мне нужно было изменить мой код с исходного:
//build the signature
$key = 'secret';
$signature = hash_hmac('SHA256',"$headers_encoded.$payload_encoded",$key);
//build and return the token
$token = "$headers_encoded.$payload_encoded.$signature";
Для исправленных:
//build the signature
$key = 'secret';
$signature = hash_hmac('SHA256',"$headers_encoded.$payload_encoded",$key,true);
$signature_encoded = base64url_encode($signature);
//build and return the token
$token = "$headers_encoded.$payload_encoded.$signature_encoded";
echo $token;
Других решений пока нет …