forked from jwt/ruby-jwt
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjwt.rb
More file actions
76 lines (60 loc) · 2.34 KB
/
jwt.rb
File metadata and controls
76 lines (60 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# frozen_string_literal: true
require 'base64'
require 'jwt/decode'
require 'jwt/default_options'
require 'jwt/encode'
require 'jwt/error'
require 'jwt/json'
require 'jwt/signature'
# JSON Web Token implementation
#
# Should be up to date with the latest spec:
# https://tools.ietf.org/html/rfc7519#section-4.1.5
module JWT
extend JWT::Json
include JWT::DefaultOptions
module_function
def decoded_segments(jwt, key = nil, verify = true, custom_options = {}, &keyfinder)
raise(JWT::DecodeError, 'Nil JSON web token') unless jwt
merged_options = DEFAULT_OPTIONS.merge(custom_options)
decoder = Decode.new jwt, key, verify, merged_options, &keyfinder
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
merged_options = DEFAULT_OPTIONS.merge(custom_options)
decoder = Decode.new jwt, key, verify, merged_options, &keyfinder
header, payload, signature, signing_input = decoder.decode_segments
decode_verify_signature(key, header, payload, signature, signing_input, merged_options, &keyfinder) if verify
decoder.verify
raise(JWT::DecodeError, 'Not enough or too many segments') unless header && payload
[payload, header]
end
def decode_verify_signature(key, header, payload, signature, signing_input, options, &keyfinder)
algo, key = signature_algorithm_and_key(header, payload, key, &keyfinder)
raise(JWT::IncorrectAlgorithm, 'An algorithm must be specified') unless options[:algorithm]
raise(JWT::IncorrectAlgorithm, 'Expected a different algorithm') unless algo == options[:algorithm]
Signature.verify(algo, key, signing_input, signature)
end
def signature_algorithm_and_key(header, payload, key, &keyfinder)
if keyfinder
key = if keyfinder.arity == 2
yield(header, payload)
else
yield(header)
end
raise JWT::DecodeError, 'No verification key available' unless key
end
[header['alg'], key]
end
def base64url_decode(str)
Decode.base64url_decode(str)
end
def base64url_encode(str)
Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
end
end