jwt_easy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9e7c1abc2e2e5159abc61e45102226fe2b252f9b
4
+ data.tar.gz: 7c393cced4e3786d6b5834855716827d69890671
5
+ SHA512:
6
+ metadata.gz: 9159765198fcb834e2a316b54f1eed749118cf90d1dfe89f9dc7884b9267e12705e0d9090f997b551d14d6d9dcdae2a9ef1374c21d9ae835d5c8f7416f7792e6
7
+ data.tar.gz: 26dfb051ded825aa7d6df8bf4bb4758c60cceff754f7b5fe7588e1fb520688d9a2330181187bafda0b8be5eb582cf79e9ee24aff5149eee34249e55bd959f006
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+
4
+ Documentation:
5
+ Enabled: false
6
+
7
+ Metrics/BlockLength:
8
+ Exclude:
9
+ - 'spec/**/*'
10
+ - '*.gemspec'
11
+
12
+ Metrics/LineLength:
13
+ Max: 100
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.0
5
+ before_install: gem install bundler -v 1.13.7
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in jwt_easy.gemspec
6
+ gemspec
7
+
8
+ ruby '2.4.0'
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # JWTEasy
2
+
3
+ JWTEasy is a simple wrapper for the [JWT](https://github.com/jwt/ruby-jwt) gem (version 1.x) that hopes to make generating and consuming various types of JSON web tokens a little easier.
4
+
5
+ > **Note:** Currently only supports plain, EXP and NBF tokens with HMAC HS256 encryption.
6
+
7
+ ## Usage
8
+
9
+ Generating a plain token without encryption might look something like:
10
+
11
+ ```ruby
12
+ token = JWTEasy.encode(id: 'some-identifying-information')
13
+ ```
14
+
15
+ You'd likely want to configure things before though:
16
+
17
+ ```ruby
18
+ # config/initializers/jwt_easy.rb
19
+ JWTEasy.configure do |config|
20
+ config.expiration_time = 3_600
21
+ config.secret = ENV['JWT_EASY_SECRET']
22
+ config.algorithm = JWTEasy::ALGORITHM_HMAC_HS256
23
+ end
24
+ ````
25
+
26
+ Of course you're able to consume tokens just as easily:
27
+
28
+ ```ruby
29
+ JWTEasy.decode(token).id #=> 'some-identifying-information'
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ Add this line to your application's Gemfile:
35
+
36
+ ```ruby
37
+ gem 'jwt_easy'
38
+ ```
39
+
40
+ And then execute:
41
+
42
+ $ bundle
43
+
44
+ Or install it yourself as:
45
+
46
+ $ gem install jwt_easy
47
+
48
+ ## Development
49
+
50
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
51
+
52
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
53
+
54
+ ## Contributing
55
+
56
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lshepstone/jwt_easy.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'jwt_easy'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start
data/bin/rspec ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/jwt_easy.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'jwt_easy/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'jwt_easy'
10
+ spec.version = JWTEasy::VERSION
11
+ spec.authors = ['Lawrance Shepstone']
12
+ spec.email = ['lawrance.shepstone@gmail.com']
13
+
14
+ spec.summary = 'jwt_easy'
15
+ spec.description = 'Library for generating and consuming JSON web tokens easily.'
16
+ spec.homepage = 'https://github.com/lshepstone/jwt_easy'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_dependency 'jwt', '~> 1.5'
27
+
28
+ spec.add_development_dependency 'bundler', '~> 1.13'
29
+ spec.add_development_dependency 'rake', '~> 10.0'
30
+ spec.add_development_dependency 'rspec', '~> 3.0'
31
+ spec.add_development_dependency 'rubocop', '~> 0'
32
+ spec.add_development_dependency 'pry', '~> 0'
33
+ spec.add_development_dependency 'timecop', '~> 0'
34
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # A configuration object used to define various options for encoding and decoding tokens.
5
+ #
6
+ # * This is usually not instantiated directly, but rather by way of calling
7
+ # +JWTEasy.configure+.
8
+ class Configuration
9
+ attr_writer :algorithm
10
+
11
+ attr_accessor :secret,
12
+ :expiration_time,
13
+ :not_before_time
14
+
15
+ # Gets the algorithm to use when encoding tokens
16
+ #
17
+ # * If no secret has been set, this returns 'none'
18
+ #
19
+ # @return [String] the algorithm to be used
20
+ def algorithm
21
+ secret ? (@algorithm || ALGORITHM_HMAC_HS256) : 'none'
22
+ end
23
+
24
+ # Infers the claim to observe during encoding or decoding.
25
+ #
26
+ # @return [Symbol] short name for the identified claim
27
+ def claim
28
+ if expiration_time
29
+ CLAIM_EXPIRATION_TIME
30
+ elsif not_before_time
31
+ CLAIM_NOT_BEFORE_TIME
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # Short-names for various supported claim types.
5
+ #
6
+ CLAIM_EXPIRATION_TIME = :exp
7
+ CLAIM_NOT_BEFORE_TIME = :nbf
8
+
9
+ # Algorithm identifiers for supported algorithms.
10
+ #
11
+ ALGORITHM_HMAC_HS256 = 'HS256'
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Hash
4
+ def except(*keys)
5
+ dup.except!(*keys)
6
+ end
7
+
8
+ def except!(*keys)
9
+ keys.each { |key| delete(key) }
10
+ self
11
+ end
12
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # Decoder object for decoding tokens.
5
+ #
6
+ # * This is usually not instantiated directly, but rather by way of
7
+ # calling +JWTEasy.decode+.
8
+ class Decoder
9
+ attr_reader :token,
10
+ :configuration
11
+
12
+ # Initializes a new encoder instance.
13
+ #
14
+ # * If no configuration object is passed or is +nil+, the value of
15
+ # +JWTEasy.configuration+ is used as the configuration object
16
+ #
17
+ # @param [String] token the token to be decoded
18
+ # @param [Configuration] configuration the configuration object
19
+ def initialize(token, configuration = nil)
20
+ @token = token
21
+ @configuration = configuration || JWTEasy.configuration
22
+ @headers = {}
23
+ end
24
+
25
+ # Decodes the token with the configured options.
26
+ #
27
+ # @return [Result] the result of the decoding
28
+ def decode
29
+ Result.new(*JWT.decode(token, configuration.secret, verification?, headers))
30
+ end
31
+
32
+ # Determines if verification will be used during decoding.
33
+ #
34
+ # @return [Boolean] if verification will be used or not
35
+ def verification?
36
+ configuration.secret.nil? == false
37
+ end
38
+
39
+ # Determines the headers to be used during decoding.
40
+ #
41
+ # @return [Hash] the headers to be used
42
+ def headers
43
+ @headers.tap do |headers|
44
+ headers[:algorithm] = configuration.algorithm if verification?
45
+
46
+ case configuration.claim
47
+ when CLAIM_EXPIRATION_TIME
48
+ headers[:validate_exp] = true
49
+ when CLAIM_NOT_BEFORE_TIME
50
+ headers[:validate_nbf] = true
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # Encoder object for generating new tokens.
5
+ #
6
+ # * This is usually not instantiated directly, but rather by way of
7
+ # calling +JWTEasy.encode+.
8
+ class Encoder
9
+ attr_reader :data,
10
+ :configuration
11
+
12
+ # Initializes a new encoder instance.
13
+ #
14
+ # * If no configuration object is passed or is +nil+, the value of
15
+ # +JWTEasy.configuration+ is used as the configuration object
16
+ #
17
+ # @param [Object] data the data to be encoded
18
+ # @param [Configuration] configuration the configuration object
19
+ def initialize(data, configuration = nil)
20
+ @data = data
21
+ @configuration = configuration || JWTEasy.configuration
22
+ end
23
+
24
+ # Encodes the data with the configured options.
25
+ #
26
+ # @return [String] the encoded token
27
+ def encode
28
+ JWT.encode(payload, configuration.secret, configuration.algorithm)
29
+ end
30
+
31
+ # Determines the structure of the payload to be encoded.
32
+ #
33
+ # @return [Object] the payload to be encoded
34
+ def payload
35
+ case configuration.claim
36
+ when CLAIM_EXPIRATION_TIME
37
+ { data: data, exp: expiration_time }
38
+ when CLAIM_NOT_BEFORE_TIME
39
+ { data: data, nbf: not_before_time }
40
+ else
41
+ data
42
+ end
43
+ end
44
+
45
+ # Calculates the expiration time if configured.
46
+ #
47
+ # @return [Integer] the expiration time
48
+ def expiration_time
49
+ Time.now.to_i + configuration.expiration_time
50
+ end
51
+
52
+ # Calculates the not before time if configured.
53
+ #
54
+ # @return [Integer] the not before time
55
+ def not_before_time
56
+ Time.now.to_i - configuration.not_before_time
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ # Result object that represents a decoded token.
5
+ #
6
+ # * This is usually not instantiated directly, but rather by way of
7
+ # calling +JWTEasy.encode+.
8
+ class Result
9
+ CLAIM_KEYS = [
10
+ CLAIM_EXPIRATION_TIME,
11
+ CLAIM_NOT_BEFORE_TIME
12
+ ].freeze
13
+
14
+ attr_reader :payload,
15
+ :headers
16
+
17
+ # Initializes a new result instance.
18
+ #
19
+ # @param [Object] payload from decoding a token
20
+ # @param [Hash] headers from decoding a token
21
+ def initialize(payload = nil, headers = nil)
22
+ @payload = payload
23
+ @headers = headers
24
+ end
25
+
26
+ # Determines the encoded data from the payload structure.
27
+ #
28
+ # * If the payload is a hash that contains a claim key alongside other data
29
+ # attributes, only a hash with the data attributes will be returned.
30
+ #
31
+ # * If the payload is hash that contains data in a data attribute alongside
32
+ # any claim keys, the value of the data attribute is returned.
33
+ #
34
+ # * If the payload is anything but a hash, the payload is returned.
35
+ #
36
+ # @return [Object] the data encoded with the payload
37
+ def data
38
+ @data ||= if payload.is_a?(Hash)
39
+ if claim && payload.key?('data')
40
+ payload['data']
41
+ else
42
+ payload.except(*CLAIM_KEYS.map(&:to_s))
43
+ end
44
+ else
45
+ payload
46
+ end
47
+ end
48
+
49
+ # Infers the claim that was observed during decoding.
50
+ #
51
+ # @return [Symbol] short name for the identified claim
52
+ def claim
53
+ @claim ||= CLAIM_KEYS.find { |claim| payload&.key?(claim.to_s) }
54
+ end
55
+
56
+ def method_missing(method, *arguments, &block)
57
+ data.is_a?(Hash) && data.key?(method.to_s) ? data[method.to_s] : super
58
+ end
59
+
60
+ def respond_to_missing?(method, _include_private = false)
61
+ data.is_a?(Hash) && data.key?(method.to_s) || super
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTEasy
4
+ VERSION = '0.1.0'
5
+ end
data/lib/jwt_easy.rb ADDED
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jwt'
4
+ require 'jwt_easy/core_ext/hash'
5
+ require 'jwt_easy/constants'
6
+ require 'jwt_easy/encoder'
7
+ require 'jwt_easy/configuration'
8
+ require 'jwt_easy/result'
9
+ require 'jwt_easy/decoder'
10
+ require 'jwt_easy/version'
11
+
12
+ # JWTEasy is a simple wrapper for the JWT gem that hopes to make generating and consuming various
13
+ # types of JSON web tokens a little easier.
14
+ #
15
+ # == Usage
16
+ #
17
+ # Generating a plain token without encryption might look something like:
18
+ #
19
+ # token = JWTEasy.encode(id: 'some-identifying-information')
20
+ #
21
+ # You'd likely want to configure things before though:
22
+ #
23
+ # # config/initializers/jwt_easy.rb
24
+ # JWTEasy.configure do |config|
25
+ # config.not_before_time = 3_600
26
+ # config.secret = ENV['JWT_EASY_SECRET']
27
+ # config.algorithm = JWTEasy::ALGORITHM_HMAC_HS256
28
+ # end
29
+ #
30
+ # Of course you're able to consume tokens just as easily:
31
+ #
32
+ # JWTEasy.decode(token).id #=> 'some-identifying-information'
33
+ #
34
+ # @see JWTEasy.encode
35
+ # @see JWTEasy.decode
36
+ # @see JWTEasy.configure
37
+ module JWTEasy
38
+ module_function
39
+
40
+ # Gets the configuration object.
41
+ #
42
+ # If none was set, a new configuration object is instantiated and returned.
43
+ #
44
+ # @return [Configuration] the configuration object
45
+ #
46
+ # @see Configuration
47
+ def configuration
48
+ @configuration ||= Configuration.new
49
+ end
50
+
51
+ # Allows for configuring the library using a block.
52
+ #
53
+ # @example Configuration using a block
54
+ # JWTEasy.configure do |config|
55
+ # # ...
56
+ # end
57
+ #
58
+ # @see Configuration
59
+ def configure
60
+ yield(configuration) if block_given?
61
+ end
62
+
63
+ # Instantiates a new encoder and encodes the provided data and the global configuration object.
64
+ #
65
+ # @example Generate a token from some data
66
+ # JWTEasy.encode(id: 'some-identifying-information')
67
+ #
68
+ # @param [Object] data the data to be encoded in the token
69
+ #
70
+ # @return [String] JSON web token
71
+ #
72
+ # @see Encoder
73
+ def encode(data)
74
+ Encoder.new(data, configuration).encode
75
+ end
76
+
77
+ # Instantiates a new decoder with the provided data and the global configuration object.
78
+ #
79
+ # @example Decode a token
80
+ # JWTEasy.decode(token)
81
+ #
82
+ # @param [String] token the token to be decoded
83
+ #
84
+ # @return [Result] Result of the decode
85
+ #
86
+ # @see Encoder
87
+ def decode(token)
88
+ Decoder.new(token, configuration).decode
89
+ end
90
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jwt_easy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lawrance Shepstone
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-09-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jwt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: timecop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Library for generating and consuming JSON web tokens easily.
112
+ email:
113
+ - lawrance.shepstone@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".rspec"
120
+ - ".rubocop.yml"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - README.md
124
+ - Rakefile
125
+ - bin/console
126
+ - bin/rspec
127
+ - bin/setup
128
+ - jwt_easy.gemspec
129
+ - lib/jwt_easy.rb
130
+ - lib/jwt_easy/configuration.rb
131
+ - lib/jwt_easy/constants.rb
132
+ - lib/jwt_easy/core_ext/hash.rb
133
+ - lib/jwt_easy/decoder.rb
134
+ - lib/jwt_easy/encoder.rb
135
+ - lib/jwt_easy/result.rb
136
+ - lib/jwt_easy/version.rb
137
+ homepage: https://github.com/lshepstone/jwt_easy
138
+ licenses:
139
+ - MIT
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.6.8
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: jwt_easy
161
+ test_files: []