Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merged conflicting changes.

  • Loading branch information...
commit 941536d76e574b4b558ae41425ddfffccd2fb451 2 parents 2fd6ea2 + 321a20c
@sporkmonger sporkmonger authored
View
5 Gemfile
@@ -1,6 +1,7 @@
source :rubygems
gem 'json', '>= 1.2.4'
+gem 'multi_json', '~> 1.0'
gem 'jruby-openssl', :platforms => :jruby
group :development do
@@ -8,6 +9,6 @@ group :development do
end
group :test, :development do
- gem 'rake', '>= 0.9.0'
- gem 'rspec', '>= 2.11.0'
+ gem 'rake'
+ gem 'rspec'
end
View
1  README.md
@@ -56,6 +56,7 @@ The tests are written with rspec. Given you have rake and rspec, you can run tes
## Contributors
+ * Bob Aman <bob@sporkmonger.com>
* Jordan Brough <github.jordanb@xoxy.net>
* Ilya Zhitomirskiy <ilya@joindiaspora.com>
* Daniel Grippi <daniel@joindiaspora.com>
View
2  Rakefile
@@ -8,7 +8,7 @@ Echoe.new('jwt', '0.1.5') do |p|
p.author = "Jeff Lindsay"
p.email = "jeff.lindsay@twilio.com"
p.ignore_pattern = ["tmp/*"]
- p.runtime_dependencies = ["json >=1.2.4"]
+ p.runtime_dependencies = ["multi_json ~> 1.0"]
p.development_dependencies = ["echoe >=4.6.3"]
end
View
36 lib/jwt.rb
@@ -1,16 +1,16 @@
-#
+#
# JSON Web Token implementation
-#
+#
# Should be up to date with the latest spec:
# http://self-issued.info/docs/draft-jones-json-web-token-06.html
require "base64"
require "openssl"
-require "json"
+require "multi_json"
module JWT
class DecodeError < Exception; end
-
+
def self.sign(algorithm, msg, key)
if ["HS256", "HS384", "HS512"].include?(algorithm)
sign_hmac(algorithm, msg, key)
@@ -32,22 +32,22 @@ def self.verify_rsa(algorithm, public_key, signing_input, signature)
def self.sign_hmac(algorithm, msg, key)
OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new(algorithm.sub('HS', 'sha')), key, msg)
end
-
+
def self.base64url_decode(str)
str += '=' * (4 - str.length.modulo(4))
Base64.decode64(str.gsub("-", "+").gsub("_", "/"))
end
-
+
def self.base64url_encode(str)
Base64.encode64(str).gsub("+", "-").gsub("/", "_").gsub("\n", "").gsub('=', '')
- end
-
- def self.encode(payload, key, algorithm='HS256')
+ end
+
+ def self.encode(payload, key, algorithm='HS256', header_fields={})
algorithm ||= "none"
segments = []
- header = {"typ" => "JWT", "alg" => algorithm}
- segments << base64url_encode(header.to_json)
- segments << base64url_encode(payload.to_json)
+ header = {"typ" => "JWT", "alg" => algorithm}.merge(header_fields)
+ segments << base64url_encode(MultiJson.encode(header))
+ segments << base64url_encode(MultiJson.encode(payload))
signing_input = segments.join('.')
if algorithm != "none"
signature = sign(algorithm, signing_input, key)
@@ -57,15 +57,15 @@ def self.encode(payload, key, algorithm='HS256')
end
segments.join('.')
end
-
- def self.decode(jwt, key=nil, verify=true)
+
+ def self.decode(jwt, key=nil, verify=true, &keyfinder)
segments = jwt.split('.')
raise JWT::DecodeError.new("Not enough or too many segments") unless [2,3].include? segments.length
header_segment, payload_segment, crypto_segment = segments
signing_input = [header_segment, payload_segment].join('.')
begin
- header = JSON.parse(base64url_decode(header_segment))
- payload = JSON.parse(base64url_decode(payload_segment))
+ header = MultiJson.decode(base64url_decode(header_segment))
+ payload = MultiJson.decode(base64url_decode(payload_segment))
signature = base64url_decode(crypto_segment) if verify
rescue JSON::ParserError
raise JWT::DecodeError.new("Invalid segment encoding")
@@ -73,6 +73,10 @@ def self.decode(jwt, key=nil, verify=true)
if verify == true
algo = header['alg']
+ if keyfinder
+ key = keyfinder.call(header)
+ end
+
begin
if ["HS256", "HS384", "HS512"].include?(algo)
raise JWT::DecodeError.new("Signature verification failed") unless signature == sign_hmac(algo, signing_input, key)
View
10 spec/jwt.rb → spec/jwt_spec.rb
@@ -19,6 +19,16 @@
decoded_payload.should == @payload
end
+ it "encodes and decodes JWTs with custom header fields" do
+ private_key = OpenSSL::PKey::RSA.generate(512)
+ jwt = JWT.encode(@payload, private_key, "RS256", {"kid" => 'default'})
+ decoded_payload = JWT.decode(jwt) do |header|
+ header["kid"].should == 'default'
+ private_key.public_key
+ end
+ decoded_payload.should == @payload
+ end
+
it "decodes valid JWTs" do
example_payload = {"hello" => "world"}
example_secret = 'secret'
Please sign in to comment.
Something went wrong with that request. Please try again.