本文へスキップ
ecdsa.com
ruby-jwt (Ruby)Ruby

エラーメッセージ

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 は入力をドットで分割しましたが、署名付き JWT の 3 つのセグメントが見つからなかったため、それ以外のチェックは行われていません。ruby-jwt 3.x ではクラスは `JWT::MalformedTokenError` です。これは `JWT::TokenError` のサブクラスで、その親クラスが `JWT::DecodeError` なので、既存の `rescue JWT::DecodeError` ブロックで引き続き捕捉できます。`Bearer ` プレフィックスが付いたままのトークンは 3 つに分割されますが、代わりに最初の部分で「Invalid base64 encoding」として失敗します。

発生する理由

修正方法

  1. 1.

    先にトークンを取り出して形式を確認する

    ruby-jwt に渡す前に、`Bearer <header.payload.signature>` の形式だけを受け入れ、それ以外には 401 を返してください。

    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")

関連するエラー

署名エラーデータベースをすべて見る