JWT (JSON Web Token) на PHP без использования сторонней библиотеки. Как подписать?

Существует несколько библиотек для реализации JSON Web Tokens (JWT) в PHP, таких как phpjwt . Я пишу свой собственный, очень маленький и простой класс, но не могу понять, почему моя подпись терпит неудачу, даже если я пытался придерживаться стандарта. Я пытался часами, и я застрял. Пожалуйста помоги!

Мой код прост

//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;