JWT (JSON Web Token) no PHP sem usar a biblioteca de terceiros. Como assinar?

Existem algumas bibliotecas para implementar JSON Web Tokens (JWT) no PHP, comophp-jwt. Estou escrevendo minha própria classe, muito pequena e simples, mas não consigo descobrir por que minha assinatura falha na validaçãoaqui mesmo que eu tenha tentado seguir o padrão. Estou tentando há horas e estou preso. Por favor ajude!

Meu código é simples

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

obase64url_encode função:

function base64url_encode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

Meus cabeçalhos e carga combinam perfeitamente comsite de validação JWT padrão, mas minha assinatura não corresponde, portanto meu token é sinalizado como inválido. Esse padrão parece realmente simples, então o que há de errado com minha assinatura?

questionAnswers(1)

yourAnswerToTheQuestion