跳到主要内容
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 应有的三段,因此没有再做其他检查。在 ruby-jwt 3.x 中,异常类为 `JWT::MalformedTokenError`(它是 `JWT::TokenError` 的子类,而后者又是 `JWT::DecodeError` 的子类),因此现有的 `rescue JWT::DecodeError` 代码块仍能捕获它。如果令牌还带着 `Bearer ` 前缀,它确实能拆分成三段,但会在第一段上失败,报出的是另一个错误“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")

相关错误

浏览完整的签名错误库