Сообщение об ошибке
Not enough or too many segments
Также выводится как
- Not enough or too many segments (JWT::DecodeError)
- Invalid base64 encoding (JWT::Base64DecodeError)
ruby-jwt 2.x выбрасывал `JWT::DecodeError` с тем же текстом. Если в токене остался префикс `Bearer`, выводится «Invalid base64 encoding (JWT::Base64DecodeError)».
ruby-jwt (Ruby) — JWT::DecodeError (JWT::MalformedTokenError in 3.x) from JWT.decode
Что это означает
ruby-jwt разделил входные данные по точкам и не нашёл 3 сегментов, из которых состоит подписанный JWT, поэтому больше ничего не проверял. В ruby-jwt 3.x класс ошибки — `JWT::MalformedTokenError` (подкласс `JWT::TokenError`, который сам наследуется от `JWT::DecodeError`), поэтому существующие блоки `rescue JWT::DecodeError` по-прежнему её перехватывают. Токен, у которого остался префикс `Bearer `, делится на 3 части, но вместо этой ошибки даёт «Invalid base64 encoding» уже на первой из них.
Почему это происходит
Пустое значение или не JWT
частоОтсутствующий заголовок, который `to_s` превратил в `""`, cookie сессии или непрозрачный токен доступа OAuth, который никогда не был JWT.
Заголовок Authorization декодирован целиком
часто`request.headers["Authorization"]` возвращает `Bearer eyJ…`. Отрежьте схему перед декодированием.
Зашифрованный токен
редко`JWT.decode` не поддерживает токены JWE из 5 сегментов; сначала их нужно расшифровать библиотекой для JWE.
Как исправить
- 1.
Сначала извлеките токен и проверьте его форму
Принимайте только `Bearer <header.payload.signature>` и на всё остальное отвечайте 401 ещё до того, как значение попадёт в ruby-jwt.
ruby def bearer_token(request) scheme, token = request.authorization.to_s.split(" ", 2) return nil unless scheme&.casecmp?("Bearer") && token&.count(".") == 2 token end token = bearer_token(request) or return head(:unauthorized) payload, _header = JWT.decode(token, public_key, true, algorithm: "ES256")