Module: JWT

Defined in:
lib/jwt.rb

Defined Under Namespace

Classes: DecodeError

Class Method Summary collapse

Class Method Details

.base64url_decode(str) ⇒ Object



19
20
21
22
# File 'lib/jwt.rb', line 19

def self.base64url_decode(str)
  str += '=' * (4 - str.length.modulo(4))
  Base64.decode64(str.gsub("-", "+").gsub("_", "/"))
end

.base64url_encode(str) ⇒ Object



24
25
26
# File 'lib/jwt.rb', line 24

def self.base64url_encode(str)
  Base64.encode64(str).gsub("+", "-").gsub("/", "_").gsub("\n", "").gsub('=', '')
end

.decode(jwt, key = nil, verify = true) ⇒ Object

Raises:



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/jwt.rb', line 39

def self.decode(jwt, key=nil, verify=true)
  segments = jwt.split('.')
  raise JWT::DecodeError.new("Not enough or too many segments") unless segments.length == 3
  header_segment, payload_segment, crypto_segment = segments
  signing_input = [header_segment, payload_segment].join('.')
  begin
    header = JSON.parse(base64url_decode(header_segment))
    payload = JSON.parse(base64url_decode(payload_segment))
    signature = base64url_decode(crypto_segment)
  rescue JSON::ParserError
    raise JWT::DecodeError.new("Invalid segment encoding")
  end
  if verify
    begin
      if not signature == sign(header['alg'], signing_input, key)
        raise JWT::DecodeError.new("Signature verification failed")
      end
    rescue NotImplementedError
      raise JWT::DecodeError.new("Algorithm not supported")
    end
  end
  payload
end

.encode(payload, key, algorithm = 'HS256') ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'lib/jwt.rb', line 28

def self.encode(payload, key, algorithm='HS256')
  segments = []
  header = {"typ" => "JWT", "alg" => algorithm}
  segments << base64url_encode(header.to_json)
  segments << base64url_encode(payload.to_json)
  signing_input = segments.join('.')
  signature = sign(algorithm, signing_input, key)
  segments << base64url_encode(signature)
  segments.join('.')
end

.sign(algorithm, msg, key) ⇒ Object

Raises:

  • (NotImplementedError)


14
15
16
17
# File 'lib/jwt.rb', line 14

def self.sign(algorithm, msg, key)
  raise NotImplementedError.new("Unsupported signing method") unless ["HS256", "HS384", "HS512"].include?(algorithm)
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(algorithm.sub('HS', 'sha')), key, msg)
end