Skip to content

Instantly share code, notes, and snippets.

@alebian
Created October 8, 2017 14:15
Show Gist options
  • Save alebian/2b04ef58750eef627aa16d1f4a96f74c to your computer and use it in GitHub Desktop.
Save alebian/2b04ef58750eef627aa16d1f4a96f74c to your computer and use it in GitHub Desktop.
require 'jwt'
module Token
class Builder
VALID_ALGORITHMS = ['HS256', 'RS256'].freeze
attr_reader :token
def initialize
@payload = {}
end
def fetch(key)
@payload[key.to_sym] || @payload[key.to_s]
end
alias_method :[], :fetch
def expiration(expiration_date)
add_claim(:exp, expiration_date)
end
def not_before(nbf_date = current_time)
add_claim(:nbf, nbf_date)
end
def issuer(issuer)
add_claim(:iss, issuer)
end
def subject(subject)
add_claim(:sub, subject)
end
def issued_at(issued_date = current_time)
add_claim(:iat, issued_date)
end
def jwt_id(jwt_id)
add_claim(:jti, jwt_id)
end
def add_claims(claims = {})
claims.each do |key, value|
add_claim(key, value)
end
self
end
def add_claim(key, value)
return self if value.nil?
@payload[key] = value
self
end
def sign(key, alg = VALID_ALGORITHMS.first)
raise Exceptions::InvalidAlgorithm unless VALID_ALGORITHMS.include?(alg)
@token = JWT.encode(@payload, key, alg)
self
end
private
def current_time
Time.now.to_i
end
end
end
require 'jwt'
module Token
class Decoded
def initialize(token, key, algorithm = Token::Builder::VALID_ALGORITHMS.first)
@token = token
@key = key
@algorithm = algorithm
decode!
end
def fetch(key)
@payload[key.to_sym] || @payload[key.to_s]
end
alias_method :[], :fetch
def validate!(entity, entity_custom_validation = nil)
raise Exceptions::NoEntityPresent unless entity
raise Exceptions::CantUseBefore unless can_use?
raise Exceptions::ExpiredToken if expired?
if entity_custom_validation && !valid_entity_custom_validation?(entity_custom_validation)
raise Exceptions::EntityCustomValidationError
end
end
def expired?
fetch(:exp).present? && current_time > fetch(:exp)
end
def able_to_renew?(renew_id)
fetch(:renew_date).present? && current_time < fetch(:renew_date) && valid_renew_id?(renew_id)
end
def can_use?
fetch(:nbf).present? && current_time >= fetch(:nbf)
end
private
def decode!
@payload = JWT.decode(@token, @key, true, algorithm: @algorithm)[0]
rescue StandardError
raise Exceptions::InvalidAuthorizationToken
end
def valid_entity_custom_validation?(entity_custom_validation)
entity_custom_validation == fetch(:entity_custom_validation)
end
def valid_renew_id?(renew_id)
renew_id == fetch(:renew_id)
end
def current_time
Time.now.to_i
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment