php-jwt кодирует и декодирует токены функциями JWT::encode() и JWT::decode() поверх расширения openssl и libsodium. Начиная с версии 6 объект Key (ключевой материал плюс алгоритм) обязателен, поэтому алгоритм задаёт ваш код, а не токен: токен RS256 и токен HS256, подделанный с помощью PEM-текста ключа EC, не прошли проверку с new Key($pem, 'ES256'), оба с ошибкой Incorrect key for this algorithm, а неподписанный токен отклоняется с ошибкой Algorithm not supported. Эта защита работает, только пока приложение само создаёт Key: с new Key($pem, 'HS256') подделанный токен прошёл проверку.
Версия 7.2.1 поддерживает HS256/384/512, RS256/384/512, ES256, ES384, ES256K и EdDSA. ES512 не поддерживается (Algorithm not supported), для PS256 нужен установленный пакет phpseclib/phpseclib, а PS384 и PS512 недоступны вовсе: для токенов от издателей, которые используют эти алгоритмы, нужна web-token или lcobucci/jwt. Ключи HMAC короче хеша отклоняются (Provided key is too short).
ES256 не привязан к P-256: токен с заголовком ES256, подписанный ключом P-384, библиотека сама создала и сама же приняла, хотя другие библиотеки такой токен отклоняют. Подписи ES256 преобразуются в 64-байтовый формат raw r‖s, которого требует JWS; подпись DER не проходит проверку с ошибкой Signature verification failed. Проверьте подпись токена в отладчике JWT.
Утверждения обрабатываются минимально. exp, nbf и iat проверяются, только если они есть в токене, JWT::$leeway — глобальное статическое свойство со значением 0 по умолчанию, а проверки издателя и аудитории нет вовсе, поэтому пример проверяет exp и iss сам. Для проверки по JWKS JWK::parseKeySet() превращает набор ключей в объекты Key; набор ключей поставщика можно разобрать в проверке JWKS.