Skip to content

Commit

Permalink
Merge pull request #182 from xamenrax/refactor_encode
Browse files Browse the repository at this point in the history
Basic encode module refactoring #121
  • Loading branch information
excpt committed Dec 7, 2016
2 parents 0c4182a + 7f86051 commit efa3e96
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 32 deletions.
42 changes: 10 additions & 32 deletions lib/jwt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'base64'
require 'openssl'
require 'jwt/decode'
require 'jwt/encode'
require 'jwt/error'
require 'jwt/json'

Expand Down Expand Up @@ -76,38 +77,6 @@ def sign_hmac(algorithm, msg, key)
OpenSSL::HMAC.digest(OpenSSL::Digest.new(algorithm.sub('HS', 'sha')), key, msg)
end

def base64url_encode(str)
Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
end

def encoded_header(algorithm = 'HS256', header_fields = {})
header = { 'alg' => algorithm }.merge(header_fields)
base64url_encode(encode_json(header))
end

def encoded_payload(payload)
raise InvalidPayload, 'exp claim must be an integer' if payload['exp'] && payload['exp'].is_a?(Time)
base64url_encode(encode_json(payload))
end

def encoded_signature(signing_input, key, algorithm)
if algorithm == 'none'
''
else
signature = sign(algorithm, signing_input, key)
base64url_encode(signature)
end
end

def encode(payload, key, algorithm = 'HS256', header_fields = {})
algorithm ||= 'none'
segments = []
segments << encoded_header(algorithm, header_fields)
segments << encoded_payload(payload)
segments << encoded_signature(segments.join('.'), key, algorithm)
segments.join('.')
end

def decoded_segments(jwt, key = nil, verify = true, custom_options = {}, &keyfinder)
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt

Expand All @@ -117,6 +86,11 @@ def decoded_segments(jwt, key = nil, verify = true, custom_options = {}, &keyfin
decoder.decode_segments
end

def encode(payload, key, algorithm = 'HS256', header_fields = {})
encoder = Encode.new payload, key, algorithm, header_fields
encoder.segments
end

def decode(jwt, key = nil, verify = true, custom_options = {}, &keyfinder)
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt

Expand Down Expand Up @@ -197,4 +171,8 @@ def asn1_to_raw(signature, public_key)
def base64url_decode(str)
Decode.base64url_decode(str)
end

def base64url_encode(str)
Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
end
end
49 changes: 49 additions & 0 deletions lib/jwt/encode.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true
require 'jwt/json'

# JWT::Encode module
module JWT
extend JWT::Json

# Encoding logic for JWT
class Encode
attr_reader :payload, :key, :algorithm, :header_fields, :segments

def initialize(payload, key, algorithm, header_fields)
@payload = payload
@key = key
@algorithm = algorithm
@header_fields = header_fields
@segments = encode_segments
end

private

def encoded_header(algorithm, header_fields)
header = { 'alg' => algorithm }.merge(header_fields)
JWT.base64url_encode(JWT.encode_json(header))
end

def encoded_payload(payload)
raise InvalidPayload, 'exp claim must be an integer' if payload['exp'] && payload['exp'].is_a?(Time)
JWT.base64url_encode(JWT.encode_json(payload))
end

def encoded_signature(signing_input, key, algorithm)
if algorithm == 'none'
''
else
signature = JWT.sign(algorithm, signing_input, key)
JWT.base64url_encode(signature)
end
end

def encode_segments
segments = []
segments << encoded_header(@algorithm, @header_fields)
segments << encoded_payload(@payload)
segments << encoded_signature(segments.join('.'), @key, @algorithm)
segments.join('.')
end
end
end

0 comments on commit efa3e96

Please sign in to comment.