github.com/golang-jwt/jwt/v5 analisa, valida e assina JWTs com as chaves da biblioteca padrão: []byte para HMAC, *rsa.PublicKey, *ecdsa.PublicKey e ed25519.PublicKey. A versão 5.3.1 assinou e verificou as famílias HS, RS, PS e ES e o EdDSA; ES256K e os nomes totalmente especificados Ed25519 e Ed448 não têm método de assinatura registrado.
A verificação depende da keyfunc que você passa para jwt.Parse. Cada método de assinatura confere o tipo Go da chave que recebe; assim, com uma keyfunc que retorna *ecdsa.PublicKey, um token RS256 falhou com RSA verify expects *rsa.PublicKey, e um token HS256 que usava o texto PEM como chave falhou com HMAC verify expects []byte. A proteção desaparece se a keyfunc devolver bytes brutos para qualquer token — uma keyfunc que carrega o arquivo PEM como []byte deixou esse token HS256 forjado passar na verificação do teste. Passe jwt.WithValidMethods com o algoritmo exato e mantenha a keyfunc tipada, como faz o exemplo.
alg: none só é verificado quando a keyfunc retorna o sentinela jwt.UnsafeAllowNoneSignatureType; qualquer chave real produz 'none' signature type is not allowed. O ES256 recusa uma chave P-384 no momento da assinatura com um simples key is invalid. As assinaturas ES256 são o r‖s bruto de 64 bytes que o JWS exige; uma assinatura DER falha com crypto/ecdsa: verification error, um erro que o depurador de JWT e o conversor DER ⇄ bruto ajudam a rastrear.
Na v5, a validação das claims vem ativada por padrão, mas exp é opcional — um token sem ela vale para sempre — e não há tolerância. jwt.WithExpirationRequired(), jwt.WithIssuer, jwt.WithAudience e jwt.WithLeeway fecham essas brechas; os erros podem ser identificados com errors.Is(err, jwt.ErrTokenExpired) em vez de comparar strings.
Para verificar tokens de um provedor de identidade, combine a biblioteca com um cliente JWKS e confira o que o provedor publica com o verificador de JWKS; o go-jose é a alternativa quando é preciso lidar com JWE ou JWK.