Method: Sandal.decode_token

Defined in:
lib/sandal.rb

.decode_token(token, depth = 16) {|header, options| ... } ⇒ Hash or String

Decodes and validates a signed and/or encrypted JSON Web Token, recursing into any nested tokens, and returns the payload.

The block is called with the token header as the first parameter, and should return the appropriate signature or decryption method to either validate the signature or decrypt the token as applicable. When the tokens are nested, this block will be called once per token. It can optionally have a second options parameter which can be used to override the DEFAULT_OPTIONS on a per-token basis; options are not persisted between yields.

Parameters:

  • token (String)

    The encoded JSON Web Token.

  • depth (Integer) (defaults to: 16)

    The maximum depth of token nesting to decode to.

Yield Parameters:

  • header (Hash)

    The JWT header values.

  • options (Hash)

    (Optional) A hash that can be used to override the default options.

Yield Returns:

  • (#valid? or #decrypt)

    The signature validator if the token is signed, or the token decrypter if the token is encrypted.

Returns:

  • (Hash or String)

    The payload of the token as a Hash if it was JSON, otherwise as a String.

Raises:



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/sandal.rb', line 157

def self.decode_token(token, depth = 16)
  parts = token.split(".")
  decoded_parts = decode_token_parts(parts)
  header = decoded_parts[0]

  options = DEFAULT_OPTIONS.clone
  decoder = yield header, options if block_given?

  if is_encrypted?(parts)
    payload = decoder.decrypt(parts)
    if header.has_key?("zip")
      unless header["zip"] == "DEF"
        raise Sandal::InvalidTokenError, "Invalid zip algorithm."
      end
      payload = Zlib::Inflate.inflate(payload)
    end
  else
    payload = decoded_parts[1]
    unless options[:ignore_signature]
      validate_signature(parts, decoded_parts[2], decoder) 
    end
  end

  if header.has_key?("cty") && header["cty"] =~ /\AJWT\Z/i
    if depth > 0
      if block_given?
        decode_token(payload, depth - 1, &Proc.new)
      else 
        decode_token(payload, depth - 1)
      end
    else
      payload
    end
  else
    parse_and_validate(payload, options)
  end
end