jwt 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/Manifest +4 -0
- data/Rakefile +17 -0
- data/jwt.gemspec +34 -0
- data/lib/jwt.rb +63 -0
- data/spec/jwt.rb +40 -0
- metadata +111 -0
- metadata.gz.sig +2 -0
data.tar.gz.sig
ADDED
Binary file
|
data/Manifest
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('jwt', '0.1.1') do |p|
|
6
|
+
p.description = "JSON Web Token implementation in Ruby"
|
7
|
+
p.url = "http://github.com/progrium/ruby-jwt"
|
8
|
+
p.author = "Jeff Lindsay"
|
9
|
+
p.email = "jeff.lindsay@twilio.com"
|
10
|
+
p.ignore_pattern = ["tmp/*"]
|
11
|
+
p.runtime_dependencies = ["json >=1.2.4"]
|
12
|
+
p.development_dependencies = []
|
13
|
+
end
|
14
|
+
|
15
|
+
task :test do
|
16
|
+
sh "spec spec/jwt.rb"
|
17
|
+
end
|
data/jwt.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{jwt}
|
5
|
+
s.version = "0.1.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Jeff Lindsay"]
|
9
|
+
s.cert_chain = ["/Users/progrium/.gem/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2011-02-23}
|
11
|
+
s.description = %q{JSON Web Token implementation in Ruby}
|
12
|
+
s.email = %q{jeff.lindsay@twilio.com}
|
13
|
+
s.extra_rdoc_files = ["lib/jwt.rb"]
|
14
|
+
s.files = ["Rakefile", "lib/jwt.rb", "spec/jwt.rb", "Manifest", "jwt.gemspec"]
|
15
|
+
s.homepage = %q{http://github.com/progrium/ruby-jwt}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Jwt"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{jwt}
|
19
|
+
s.rubygems_version = %q{1.4.1}
|
20
|
+
s.signing_key = %q{/Users/progrium/.gem/gem-private_key.pem}
|
21
|
+
s.summary = %q{JSON Web Token implementation in Ruby}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_runtime_dependency(%q<json>, [">= 1.2.4"])
|
28
|
+
else
|
29
|
+
s.add_dependency(%q<json>, [">= 1.2.4"])
|
30
|
+
end
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<json>, [">= 1.2.4"])
|
33
|
+
end
|
34
|
+
end
|
data/lib/jwt.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#
|
2
|
+
# JSON Web Token implementation
|
3
|
+
#
|
4
|
+
# Minimum implementation based on this spec:
|
5
|
+
# http://self-issued.info/docs/draft-jones-json-web-token-01.html
|
6
|
+
|
7
|
+
require "base64"
|
8
|
+
require "openssl"
|
9
|
+
require "json"
|
10
|
+
|
11
|
+
module JWT
|
12
|
+
class DecodeError < Exception; end
|
13
|
+
|
14
|
+
def self.sign(algorithm, msg, key)
|
15
|
+
raise NotImplementedError.new("Unsupported signing method") unless ["HS256", "HS384", "HS512"].include?(algorithm)
|
16
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(algorithm.sub('HS', 'sha')), key, msg)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.base64url_decode(str)
|
20
|
+
str += '=' * (4 - str.length.modulo(4))
|
21
|
+
Base64.decode64(str.gsub("-", "+").gsub("_", "/"))
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.base64url_encode(str)
|
25
|
+
Base64.encode64(str).gsub("+", "-").gsub("/", "_").gsub("\n", "").gsub('=', '')
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.encode(payload, key, algorithm='HS256')
|
29
|
+
segments = []
|
30
|
+
header = {"typ" => "JWT", "alg" => algorithm}
|
31
|
+
segments << base64url_encode(header.to_json)
|
32
|
+
segments << base64url_encode(payload.to_json)
|
33
|
+
signing_input = segments.join('.')
|
34
|
+
signature = sign(algorithm, signing_input, key)
|
35
|
+
segments << base64url_encode(signature)
|
36
|
+
segments.join('.')
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.decode(jwt, key=nil, verify=true)
|
40
|
+
segments = jwt.split('.')
|
41
|
+
raise JWT::DecodeError.new("Not enough or too many segments") unless segments.length == 3
|
42
|
+
header_segment, payload_segment, crypto_segment = segments
|
43
|
+
signing_input = [header_segment, payload_segment].join('.')
|
44
|
+
begin
|
45
|
+
header = JSON.parse(base64url_decode(header_segment))
|
46
|
+
payload = JSON.parse(base64url_decode(payload_segment))
|
47
|
+
signature = base64url_decode(crypto_segment)
|
48
|
+
rescue JSON::ParserError
|
49
|
+
raise JWT::DecodeError.new("Invalid segment encoding")
|
50
|
+
end
|
51
|
+
if verify
|
52
|
+
begin
|
53
|
+
if not signature == sign(header['alg'], signing_input, key)
|
54
|
+
raise JWT::DecodeError.new("Signature verification failed")
|
55
|
+
end
|
56
|
+
rescue NotImplementedError
|
57
|
+
raise JWT::DecodeError.new("Algorithm not supported")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
payload
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/spec/jwt.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require "#{File.dirname(__FILE__)}/../lib/jwt.rb"
|
3
|
+
|
4
|
+
payload = {"foo" => "bar"}
|
5
|
+
|
6
|
+
describe JWT do
|
7
|
+
it "encodes and decodes JWTs" do
|
8
|
+
secret = "secret"
|
9
|
+
jwt = JWT.encode(payload, secret)
|
10
|
+
decoded_payload = JWT.decode(jwt, secret)
|
11
|
+
decoded_payload.should == payload
|
12
|
+
end
|
13
|
+
|
14
|
+
it "decodes valid JWTs" do
|
15
|
+
example_payload = {"hello" => "world"}
|
16
|
+
example_secret = 'secret'
|
17
|
+
example_jwt = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJoZWxsbyI6ICJ3b3JsZCJ9.YjZmNmEwMmMzMmU4NmEyMjRhYzRlMmFhYTQxNWQyMTA2Y2JiNDk4NGEyN2Q5ODYzOWVkODI2ZjVjYjY5Y2EzZg'
|
18
|
+
decoded_payload = JWT.decode(example_jwt, example_secret)
|
19
|
+
decoded_payload.should == example_payload
|
20
|
+
end
|
21
|
+
|
22
|
+
it "raises exception with wrong key" do
|
23
|
+
right_secret = 'foo'
|
24
|
+
bad_secret = 'bar'
|
25
|
+
jwt_message = JWT.encode(payload, right_secret)
|
26
|
+
lambda { JWT.decode(jwt_message, bad_secret) }.should raise_error(JWT::DecodeError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "allows decoding without key" do
|
30
|
+
right_secret = 'foo'
|
31
|
+
bad_secret = 'bar'
|
32
|
+
jwt = JWT.encode(payload, right_secret)
|
33
|
+
decoded_payload = JWT.decode(jwt, bad_secret, false)
|
34
|
+
decoded_payload.should == payload
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises exception on unsupported crypto algorithm" do
|
38
|
+
lambda { JWT.encode(payload, "secret", 'HS1024') }.should raise_error(NotImplementedError)
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jwt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jeff Lindsay
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain:
|
17
|
+
- |
|
18
|
+
-----BEGIN CERTIFICATE-----
|
19
|
+
MIIDPDCCAiSgAwIBAgIBADANBgkqhkiG9w0BAQUFADBEMRUwEwYDVQQDDAxqZWZm
|
20
|
+
LmxpbmRzYXkxFjAUBgoJkiaJk/IsZAEZFgZ0d2lsaW8xEzARBgoJkiaJk/IsZAEZ
|
21
|
+
FgNjb20wHhcNMTAwNTA0MjE0NzE3WhcNMTEwNTA0MjE0NzE3WjBEMRUwEwYDVQQD
|
22
|
+
DAxqZWZmLmxpbmRzYXkxFjAUBgoJkiaJk/IsZAEZFgZ0d2lsaW8xEzARBgoJkiaJ
|
23
|
+
k/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb1P6c
|
24
|
+
/CN4l2pYBO0d5y7YHW3XJbj5d+5c1E9m2PcvUJ4Vjr7ISQM1SYpwixnWMBXBpzc1
|
25
|
+
En9YB+PYBEOOaIRh2G23aKdu7PnYQhze91qOBcHnf6LOckq25NbWQO8eaiXD3w5W
|
26
|
+
HRXOcmzigyTYRIhXBa93eMSihWAXThcfGFKNbtKerVhytT/UVHZU3pr9gCvt9vD0
|
27
|
+
aBmwMwvDlpO72eXPr5ow3Z+VzCc51iBNC07uvR/wFQ6/lS8ULBpHI9wcdo67wdv5
|
28
|
+
SaSZSGZCmG1pXov0Ahji7yqFMQ9oot5RDPZavZN3Fh3n6e2hdcSMlLgGkEGYaBVx
|
29
|
+
gdQFudko7rc5cWTdAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0G
|
30
|
+
A1UdDgQWBBRXFNQ8j0GGeMiiPWhAlHB356JPGDANBgkqhkiG9w0BAQUFAAOCAQEA
|
31
|
+
VzMJe10HfJtglbDah9h9lxv8uzK2uV7bXRcIbMCGEdx8cByM+cfKOnoWVDQBVPWA
|
32
|
+
VznqXdPsrVC70PAMMTk66ro2ciyudilVEuxEl7rhaz0tj9FzNyJUHBKCD4KpGwkC
|
33
|
+
K435qpJsHMi9k0KxY17grmsE2Hq60lFLK8ZrqgDblEAKTeaGAykMxp9KJOwAKnY2
|
34
|
+
4lUY/SVtRuTk0YXsIPNFLYUhYt7arkJtkwWV41GWhj7PbcM5uk5sGoh0aueMzY7f
|
35
|
+
TvklqXtUw3g3PcoJ8CZw68WaB2/MuJXUehRCZThhkBwi8bDKZzh4rtI/WEb1EgDs
|
36
|
+
WZqts+sMhUpDxxL+p6p6bQ==
|
37
|
+
-----END CERTIFICATE-----
|
38
|
+
|
39
|
+
date: 2011-02-23 00:00:00 -08:00
|
40
|
+
default_executable:
|
41
|
+
dependencies:
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: json
|
44
|
+
prerelease: false
|
45
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
hash: 23
|
51
|
+
segments:
|
52
|
+
- 1
|
53
|
+
- 2
|
54
|
+
- 4
|
55
|
+
version: 1.2.4
|
56
|
+
type: :runtime
|
57
|
+
version_requirements: *id001
|
58
|
+
description: JSON Web Token implementation in Ruby
|
59
|
+
email: jeff.lindsay@twilio.com
|
60
|
+
executables: []
|
61
|
+
|
62
|
+
extensions: []
|
63
|
+
|
64
|
+
extra_rdoc_files:
|
65
|
+
- lib/jwt.rb
|
66
|
+
files:
|
67
|
+
- Rakefile
|
68
|
+
- lib/jwt.rb
|
69
|
+
- spec/jwt.rb
|
70
|
+
- Manifest
|
71
|
+
- jwt.gemspec
|
72
|
+
has_rdoc: true
|
73
|
+
homepage: http://github.com/progrium/ruby-jwt
|
74
|
+
licenses: []
|
75
|
+
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options:
|
78
|
+
- --line-numbers
|
79
|
+
- --inline-source
|
80
|
+
- --title
|
81
|
+
- Jwt
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 3
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
hash: 11
|
99
|
+
segments:
|
100
|
+
- 1
|
101
|
+
- 2
|
102
|
+
version: "1.2"
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project: jwt
|
106
|
+
rubygems_version: 1.4.1
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: JSON Web Token implementation in Ruby
|
110
|
+
test_files: []
|
111
|
+
|
metadata.gz.sig
ADDED