Сообщение об ошибке
invalid algorithm
Что это означает
Значения заголовка alg токена нет в списке алгоритмов, которые принимает ваш код проверки. jsonwebtoken проверяет это ещё до работы с подписью, поэтому токен может быть подписан совершенно правильно — просто схемой, которую вы не разрешили. Этот барьер — защитный механизм, который работает так, как задумано, а не ошибка разбора.
Почему это происходит
После миграции издатель и проверяющая сторона не согласованы
частоИздатель перешёл с RS256 на ES256 (или наоборот), а проверяющая сторона по-прежнему жёстко задаёт старое значение в списке разрешённых алгоритмов. Тогда каждый новый токен отклоняется, а старые закешированные по-прежнему проходят, поэтому сбой после выкатки выглядит плавающим.
Список разрешённых алгоритмов выведен из ключа не того типа
частоНачиная с v9, если вы не передаёте параметр algorithms, jsonwebtoken выводит список разрешённых алгоритмов из ключа: если передать ему открытый ключ RSA, токены ES256 будут отклонены с «invalid algorithm», даже если вы хотели их разрешить. Ключ EC при разрешённом только RS256 приводит к такой же ошибке. (Ключ RSA с algorithms: ["ES256"] проходит эту проверку и отклоняется на следующей с сообщением «"alg" parameter for "rsa" key type must be one of: RS256, PS256, …».)
Токен от другого издателя
иногдаВ мультитенантные системы иногда приходят токены, выпущенные другим поставщиком удостоверений с другой схемой подписи. Несовпадение alg тогда лишь симптом — настоящая проблема в том, что токен вообще не должен попадать к этой проверяющей стороне.
Как исправить
- 1.
Ограничьте список разрешённых алгоритмов тем, что действительно использует издатель
Декодируйте заголовок, чтобы увидеть фактический alg, затем впишите в список разрешённых алгоритмов ровно это значение — и убедитесь, что тип ключа подходит (ключ EC для ES256, ключ RSA для RS256).
js const { header } = jwt.decode(token, { complete: true }); console.log(header.alg); // e.g. "ES256" jwt.verify(token, ecPublicKeyPem, { algorithms: ["ES256"] }); - 2.
Выкатывайте смену алгоритма в два этапа
Во время ротации ключа или алгоритма проверяющие стороны должны недолго принимать обе схемы, каждую со своим ключом, привязанным через kid, а затем снова оставить одну.
js // transition window only: jwt.verify(token, keyForKid(header.kid), { algorithms: ["ES256", "RS256"] }); // after all RS256 tokens expired: jwt.verify(token, ecPublicKeyPem, { algorithms: ["ES256"] });