Skip to content
Jonathan Perichon edited this page Nov 28, 2017 · 23 revisions

JSON::JWT

Install

gem install json-jwt

Require

require 'json/jwt'

Supported JOSE Specs

JWT, JWS, JWE, JWK, JWKs are supported.

For details, please read these pages.

Common Use-Cases

OpenID Connect ID Token

Generate

private_key = OpenSSL::PKey::RSA.new <<-PEM
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAyBKIFSH8dP6bDkGBziB6RXTTfZVTaaNSWNtIzDmgRFi6FbLo
 :
-----END RSA PRIVATE KEY-----
PEM

claims = {
  iss: 'https://idp.example.com',
  sub: '1061b047368a15d92ccd882b964a3aa4',
  aud: 'c136b3a6d4f1060316a84af73347ce18',
  nonce: 'b8c5c105b2bfd04516a13f593a91e140',
  iat: Time.now,
  exp: 5.minutes.from_now
}

id_token = JSON::JWT.new(claims)
id_token.kid = private_key.to_jwk.thumbprint
id_token = id_token.sign(private_key, :RS256)
id_token.to_s # => "eyJ.."

Decode & Verify

jwk_set = JSON::JWK::Set.new(
  JSON.parse(
    RestClient.get(idp_jwks_url)
  )
)
id_token = JSON::JWT.decode id_token_string, jwk_set
unless (
  id_token[:iss] == expected_iss &&
  id_token[:aud] == expected_aud &&
  id_token[:sub].present? &&
  id_token[:nonce] == expected_nonce &&
  Time.at(id_token[:iat]).between?(30.seconds.ago, Time.now) &&
  Time.at(id_token[:exp]) > Time.now
)
  raise 'ID Token Verification Failed!'
end

Decode without verifying (not recommended, use for debugging only)

id_token = JSON::JWT.decode id_token_string, :skip_verification
puts id_token.to_json

Singed and Encrypted JWT

Sign then Encrypt

payload = {
  foo: 'bar'
}
jwt = JSON::JWT.new payload
jws = jwt.sign sender_private_key
jwe = jws.encrypt recipient_public_key
jwe.to_s

Decrypt then Verify

jwe = JSON::JWT.decode jwe_string, recipient_private_key
jwt = JSON::JWT.decode jwe.plain_text, sender_public_key
jwt[:foo] # => 'bar'