Module: Sandal

Defined in:
lib/sandal.rb,
lib/sandal/enc.rb,
lib/sandal/sig.rb,
lib/sandal/util.rb,
lib/sandal/claims.rb,
lib/sandal/sig/es.rb,
lib/sandal/sig/hs.rb,
lib/sandal/sig/rs.rb,
lib/sandal/enc/alg.rb,
lib/sandal/version.rb,
lib/sandal/enc/agcm.rb,
lib/sandal/enc/acbc_hs.rb,
lib/sandal/enc/alg/direct.rb,
lib/sandal/enc/alg/rsa1_5.rb,
lib/sandal/enc/alg/rsa_oaep.rb

Overview

A library for creating and reading JSON Web Tokens (JWT).

Defined Under Namespace

Modules: Claims, Enc, Sig, Util Classes: ClaimError, TokenError

Constant Summary collapse

DEFAULT_OPTIONS =

The default options for token handling.

max_clock_skew

The maximum clock skew, in seconds, when validating times.

valid_iss

A list of valid token issuers, if issuer validation is required.

valid_aud

A list of valid audiences, if audience validation is required.

validate_exp

Whether the expiry date of the token is validated.

validate_nbf

Whether the not-before date of the token is validated.

validate_signature

Whether the signature of signed (JWS) tokens is validated.

{
  max_clock_skew: 300,
  valid_iss: [],
  valid_aud: [],
  validate_exp: true,
  validate_nbf: true,
  validate_signature: true
}
VERSION =

The semantic version of the library.

'0.2.0'

Class Method Summary collapse

Class Method Details

.decode_token(token) {|header, options| ... } ⇒ Hash/String

Decodes and validates a signed JSON Web Token (JWS).

The block is called with the token header as the first parameter, and should return the appropriate Sig to validate the signature. It can optionally have a second options parameter which can be used to override the DEFAULT_OPTIONS on a per-token basis.

Parameters:

  • token (String)

    The encoded JSON Web Token.

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

    The signature validator.

Returns:

  • (Hash/String)

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

Raises:

  • (Sandal::TokenError)

    The token format is invalid, or validation of the token failed.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/sandal.rb', line 77

def self.decode_token(token)
  parts = token.split('.')
  header, payload, signature = decode_jws_token_parts(parts)

  options = DEFAULT_OPTIONS.clone
  validator = yield header, options if block_given?
  validator ||= Sandal::Sig::None.instance

  if options[:validate_signature]
    secured_input = parts.take(2).join('.')
    raise TokenError, 'Invalid signature.' unless validator.valid?(signature, secured_input)
  end

  parse_and_validate(payload, header['cty'], options)
end

.decrypt_token(token) {|header, options| ... } ⇒ Hash/String

Decrypts and validates an encrypted JSON Web Token (JWE).

Parameters:

  • token (String)

    The encrypted JSON Web Token.

Yield Parameters:

  • header (Hash)

    The JWT header values.

  • options (Hash)

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

Yield Returns:

  • (#decrypt)

    The token decrypter.

Returns:

  • (Hash/String)

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

Raises:

  • (Sandal::TokenError)

    The token format is invalid, or decryption/validation of the token failed.



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/sandal.rb', line 116

def self.decrypt_token(token)
  parts = token.split('.')
  decoded_parts = decode_jwe_token_parts(parts)
  header = decoded_parts[0]

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

  payload = decrypter.decrypt(parts, decoded_parts)
  parse_and_validate(payload, header['cty'], options)
end

.default!(defaults) ⇒ Hash

Overrides the default options.

Parameters:

  • defaults (Hash)

    The options to override (see DEFAULT_OPTIONS for details).

Returns:

  • (Hash)

    The new default options.



40
41
42
# File 'lib/sandal.rb', line 40

def self.default!(defaults)
  DEFAULT_OPTIONS.merge!(defaults)
end

.encode_token(payload, signer, header_fields = nil) ⇒ String

Creates a signed JSON Web Token (JWS).

Parameters:

  • payload (String/Hash)

    The payload of the token. Hashes will be encoded as JSON.

  • signer (#name, #sign)

    The token signer, which may be nil for an unsigned token.

  • header_fields (Hash) (defaults to: nil)

    Header fields for the token (note: do not include ‘alg’).

Returns:

  • (String)

    A signed JSON Web Token.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/sandal.rb', line 50

def self.encode_token(payload, signer, header_fields = nil)
  signer ||= Sandal::Sig::None.instance

  header = {}
  header['alg'] = signer.name if signer.name != Sandal::Sig::None.instance.name
  header = header_fields.merge(header) if header_fields
  header = MultiJson.dump(header)

  payload = MultiJson.dump(payload) unless payload.is_a?(String)

  secured_input = [header, payload].map { |part| Sandal::Util.base64_encode(part) }.join('.')
  signature = signer.sign(secured_input)
  [secured_input, Sandal::Util.base64_encode(signature)].join('.')
end

.encrypt_token(payload, encrypter, header_fields = nil) ⇒ String

Creates an encrypted JSON Web Token (JWE).

Parameters:

  • payload (String)

    The payload of the token.

  • encrypter (Sandal::Enc)

    The token encrypter.

  • header_fields (Hash) (defaults to: nil)

    Header fields for the token (note: do not include ‘alg’ or ‘enc’).

Returns:

  • (String)

    An encrypted JSON Web Token.



99
100
101
102
103
104
105
106
# File 'lib/sandal.rb', line 99

def self.encrypt_token(payload, encrypter, header_fields = nil)
  header = {}
  header['enc'] = encrypter.name
  header['alg'] = encrypter.alg.name
  header = header_fields.merge(header) if header_fields

  encrypter.encrypt(header, payload)
end