class Blunt::Token
Constants
- ALGORITHM
- EXPIRY_TIME
Public Class Methods
create(sub)
click to toggle source
# File lib/blunt/token.rb, line 26 def self.create(sub) new(repo.create(user_id: sub)) end
new(token)
click to toggle source
# File lib/blunt/token.rb, line 10 def initialize(token) if token.is_a? String @payload = begin decode(token) rescue nil end else @payload = { sub: token.user_id, jti: encrypt(token.id), exp: token.created_at.to_i + EXPIRY_TIME } end end
Private Class Methods
repo()
click to toggle source
# File lib/blunt/token.rb, line 84 def self.repo @repo ||= RefreshTokenRepository.new end
Public Instance Methods
inspect()
click to toggle source
# File lib/blunt/token.rb, line 30 def inspect "\#<Blunt::Token #{to_s}>" end
invalidate!()
click to toggle source
# File lib/blunt/token.rb, line 69 def invalidate! # Destroy refresh token repo.delete(jti) rescue nil ensure @payload = nil end
sub()
click to toggle source
# File lib/blunt/token.rb, line 42 def sub @payload[:sub] end
to_h()
click to toggle source
# File lib/blunt/token.rb, line 38 def to_h @payload end
to_s()
click to toggle source
# File lib/blunt/token.rb, line 34 def to_s to_h ? encode : nil end
valid?()
click to toggle source
# File lib/blunt/token.rb, line 46 def valid? if @payload.nil? # Invalid token format false elsif @payload[:exp].to_i <= Time.now.to_i # Access token expired record = repo.find(jti) if record && record.valid? # Refresh token valid @payload[:exp] = Time.now.to_i + EXPIRY_TIME repo.update(record, {}) if record.respond_to?(:updated_at) @encoded = nil encode else # Refresh token expired false end else # Access token valid true end end
Private Instance Methods
decode(token)
click to toggle source
# File lib/blunt/token.rb, line 100 def decode(token) raise JWT::DecodeError, 'Nil JSON web token' unless token decoder = JWT::Decode.new(token, true) header, payload, signature, signing_input = decoder.decode_segments # Verify signature JWT.decode_verify_signature(secret, header, payload, signature, signing_input, algorithm: ALGORITHM) # Verify JWT format raise JWT::DecodeError, 'Incorrect number of segments' unless header && payload payload = payload.map{ |k,v| [k.to_sym, v] }.to_h # Verify Blunt format raise JWT::DecodeError, 'JWT claims do not meet Blunt specifications' unless payload.key?(:sub) && payload.key?(:exp) && payload.key?(:jti) payload end
decrypt(encrypted)
click to toggle source
# File lib/blunt/token.rb, line 128 def decrypt(encrypted) string = Base64.decode64(encrypted) cipher = OpenSSL::Cipher::AES256.new(:CBC) cipher.decrypt cipher.key = Digest::SHA256.digest(secret) cipher.iv = string.slice!(0, 16) cipher.update(string) + cipher.final end
encode()
click to toggle source
# File lib/blunt/token.rb, line 96 def encode @encoded ||= JWT::Encode.new(@payload, secret, ALGORITHM, {}).segments end
encrypt(string)
click to toggle source
Two-way encryption methods for JTI
# File lib/blunt/token.rb, line 119 def encrypt(string) cipher = OpenSSL::Cipher::AES256.new(:CBC) cipher.encrypt cipher.key = Digest::SHA256.digest(secret) cipher.iv = iv = cipher.random_iv encrypted = iv + cipher.update(string.to_s) + cipher.final Base64.encode64(encrypted).gsub(/\s/, '') end
jti()
click to toggle source
# File lib/blunt/token.rb, line 88 def jti decrypt(@payload[:jti]) end
repo()
click to toggle source
# File lib/blunt/token.rb, line 80 def repo self.class.repo end
secret()
click to toggle source
# File lib/blunt/token.rb, line 92 def secret @secret ||= ENV['BLUNT_SECRET'] end