O php-jwt codifica e decodifica tokens com JWT::encode() e JWT::decode() sobre a extensão openssl e a libsodium. Desde a versão 6, um objeto Key — o material da chave mais o algoritmo — é obrigatório, então o algoritmo vem do seu código, e não do token: um token RS256 e um token HS256 forjado com o texto PEM da chave EC falharam contra new Key($pem, 'ES256') com Incorrect key for this algorithm, e um token sem assinatura falha com Algorithm not supported. A proteção depende inteiramente da Key que a aplicação monta: new Key($pem, 'HS256') verificou o token forjado.
A versão 7.2.1 trabalha com HS256/384/512, RS256/384/512, ES256, ES384, ES256K e EdDSA. Não há suporte a ES512 (Algorithm not supported), o PS256 exige o phpseclib/phpseclib instalado, e PS384 e PS512 simplesmente não estão disponíveis — tokens de emissores que usam esses algoritmos precisam do web-token ou do lcobucci/jwt. Chaves HMAC menores que o hash são rejeitadas (Provided key is too short).
O ES256 não fica restrito à P-256: um token assinado com uma chave P-384 sob um cabeçalho ES256 foi produzido e aceito pela própria biblioteca, embora outras bibliotecas o recusem. As assinaturas ES256 são convertidas no r‖s bruto de 64 bytes que o JWS exige; uma assinatura DER falha com Signature verification failed. Confira a assinatura de um token no depurador de JWT.
O tratamento das claims é mínimo. exp, nbf e iat só são verificadas quando presentes, JWT::$leeway é uma variável estática global com padrão 0, e não há nenhuma validação de emissor nem de público-alvo — o exemplo verifica exp e iss por conta própria. Para a verificação baseada em JWKS, JWK::parseKeySet() converte um conjunto de chaves em objetos Key; inspecione o conjunto de um provedor com o verificador de JWKS.