grape-jwt-authentication 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6a78c43fa11b24e40395c34bbc802f61c6e4646c
4
+ data.tar.gz: ca386d7ac9298045d93e38b0c6df2c3e8ab1dcae
5
+ SHA512:
6
+ metadata.gz: 1b234415911e6f3f2820d9511af016e290ed4723521374913d9cb5b5e05925722a9222f48016c7f4a75f88ee30aa901aaa702f8699e86792e4ed9d58fab439c6
7
+ data.tar.gz: 1557a1c9a4fc4acb8cf77be68fbaf4f5417753bc5e859917508bd334e36ca9449e9c483119b009158f9d0ac4202413a372ed2c4638d45444e0e9d6ce9594139a
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/api/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,43 @@
1
+ require: rubocop-rspec
2
+
3
+ Rails:
4
+ Enabled: true
5
+
6
+ Documentation:
7
+ Enabled: true
8
+
9
+ AllCops:
10
+ DisplayCopNames: true
11
+ TargetRubyVersion: 2.3
12
+ Exclude:
13
+ - db/schema.rb
14
+ - bin/**/*
15
+ - db/migrate/**/*
16
+ - vendor/cache/**/*
17
+ - vendor/bundle/**/*
18
+ - build/**/*
19
+
20
+ Metrics/BlockLength:
21
+ Exclude:
22
+ # Because of the Grape DSL
23
+ - lib/**/*.rb
24
+ - Rakefile
25
+ - grape-jwt-authentication.gemspec
26
+ - spec/**/*.rb
27
+ - '**/*.rake'
28
+
29
+ # Document all the things.
30
+ Style/DocumentationMethod:
31
+ Enabled: true
32
+ RequireForNonPublicMethods: true
33
+
34
+ # It's a deliberate idiom in RSpec.
35
+ # See: https://github.com/bbatsov/rubocop/issues/4222
36
+ Lint/AmbiguousBlockAssociation:
37
+ Exclude:
38
+ - "spec/**/*"
39
+
40
+ # Because +expect_any_instance_of().to have_received()+ is not
41
+ # supported with the +with(hash_including)+ matchers
42
+ RSpec/MessageSpies:
43
+ EnforcedStyle: receive
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ env:
2
+ global:
3
+ - CC_TEST_REPORTER_ID=6e5d2de1ccc0412cdc8d01fdddc560fe3051b14f1c15fea55b0d6e32e27a81cf
4
+
5
+ sudo: false
6
+ language: ruby
7
+ rvm:
8
+ - 2.2
9
+ - 2.3
10
+ - 2.4
11
+
12
+ before_install: gem install bundler
13
+
14
+ before_script:
15
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
16
+ - chmod +x ./cc-test-reporter
17
+ - ./cc-test-reporter before-build
18
+
19
+ after_script:
20
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ### 1.0.1
2
+
3
+ * First public release of the gem
4
+
5
+ ### 1.0.0
6
+
7
+ * Yanked, published with the wrong account
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in grape-jwt-authentication.gemspec
8
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,114 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ grape-jwt-authentication (1.0.1)
5
+ activesupport (>= 3.2.0)
6
+ grape (~> 1.0)
7
+ httparty
8
+ jwt (~> 2.1)
9
+ recursive-open-struct (~> 1.0)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ activesupport (5.1.4)
15
+ concurrent-ruby (~> 1.0, >= 1.0.2)
16
+ i18n (~> 0.7)
17
+ minitest (~> 5.1)
18
+ tzinfo (~> 1.1)
19
+ addressable (2.5.2)
20
+ public_suffix (>= 2.0.2, < 4.0)
21
+ axiom-types (0.1.1)
22
+ descendants_tracker (~> 0.0.4)
23
+ ice_nine (~> 0.11.0)
24
+ thread_safe (~> 0.3, >= 0.3.1)
25
+ builder (3.2.3)
26
+ coercible (1.0.0)
27
+ descendants_tracker (~> 0.0.1)
28
+ concurrent-ruby (1.0.5)
29
+ crack (0.4.3)
30
+ safe_yaml (~> 1.0.0)
31
+ descendants_tracker (0.0.4)
32
+ thread_safe (~> 0.3, >= 0.3.1)
33
+ diff-lcs (1.3)
34
+ docile (1.1.5)
35
+ equalizer (0.0.11)
36
+ grape (1.0.1)
37
+ activesupport
38
+ builder
39
+ mustermann-grape (~> 1.0.0)
40
+ rack (>= 1.3.0)
41
+ rack-accept
42
+ virtus (>= 1.0.0)
43
+ hashdiff (0.3.7)
44
+ httparty (0.15.6)
45
+ multi_xml (>= 0.5.2)
46
+ i18n (0.9.1)
47
+ concurrent-ruby (~> 1.0)
48
+ ice_nine (0.11.2)
49
+ json (2.1.0)
50
+ jwt (2.1.0)
51
+ minitest (5.10.3)
52
+ multi_xml (0.6.0)
53
+ mustermann (1.0.1)
54
+ mustermann-grape (1.0.0)
55
+ mustermann (~> 1.0.0)
56
+ public_suffix (3.0.1)
57
+ rack (2.0.3)
58
+ rack-accept (0.4.5)
59
+ rack (>= 0.4)
60
+ rack-test (0.8.2)
61
+ rack (>= 1.0, < 3)
62
+ rake (10.5.0)
63
+ recursive-open-struct (1.0.5)
64
+ rspec (3.7.0)
65
+ rspec-core (~> 3.7.0)
66
+ rspec-expectations (~> 3.7.0)
67
+ rspec-mocks (~> 3.7.0)
68
+ rspec-core (3.7.0)
69
+ rspec-support (~> 3.7.0)
70
+ rspec-expectations (3.7.0)
71
+ diff-lcs (>= 1.2.0, < 2.0)
72
+ rspec-support (~> 3.7.0)
73
+ rspec-mocks (3.7.0)
74
+ diff-lcs (>= 1.2.0, < 2.0)
75
+ rspec-support (~> 3.7.0)
76
+ rspec-support (3.7.0)
77
+ safe_yaml (1.0.4)
78
+ simplecov (0.15.1)
79
+ docile (~> 1.1.0)
80
+ json (>= 1.8, < 3)
81
+ simplecov-html (~> 0.10.0)
82
+ simplecov-html (0.10.2)
83
+ thread_safe (0.3.6)
84
+ timecop (0.9.1)
85
+ tzinfo (1.2.4)
86
+ thread_safe (~> 0.1)
87
+ vcr (3.0.3)
88
+ virtus (1.0.5)
89
+ axiom-types (~> 0.1)
90
+ coercible (~> 1.0)
91
+ descendants_tracker (~> 0.0, >= 0.0.3)
92
+ equalizer (~> 0.0, >= 0.0.9)
93
+ webmock (3.1.1)
94
+ addressable (>= 2.3.6)
95
+ crack (>= 0.3.2)
96
+ hashdiff
97
+
98
+ PLATFORMS
99
+ ruby
100
+
101
+ DEPENDENCIES
102
+ bundler (~> 1.16)
103
+ grape-jwt-authentication!
104
+ rack (~> 2.0)
105
+ rack-test (~> 0.8.2)
106
+ rake (~> 10.0)
107
+ rspec (~> 3.0)
108
+ simplecov (~> 0.15)
109
+ timecop (~> 0.9.1)
110
+ vcr (~> 3.0)
111
+ webmock (~> 3.1)
112
+
113
+ BUNDLED WITH
114
+ 1.16.0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 HAUSGOLD | talocasa GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,391 @@
1
+ ![grape-jwt-authentication](doc/assets/project.png)
2
+
3
+ [![Build Status](https://api.travis-ci.org/hausgold/grape-jwt-authentication.svg)](https://travis-ci.org/hausgold/grape-jwt-authentication)
4
+ [![Gem Version](https://badge.fury.io/rb/grape-jwt-authentication.svg)](https://badge.fury.io/rb/grape-jwt-authentication)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/446f3eff18bebff9c174/maintainability)](https://codeclimate.com/github/hausgold/grape-jwt-authentication/maintainability)
6
+ [![Test Coverage](https://codeclimate.com/github/hausgold/grape-jwt-authentication/badges/coverage.svg)](https://codeclimate.com/github/hausgold/grape-jwt-authentication/coverage)
7
+
8
+ This gem is dedicated to easily integrate a JWT authentication to your
9
+ [Grape](https://github.com/ruby-grape/grape) API. The real authentication
10
+ functionality must be provided by the user and this makes this gem highy
11
+ flexible on the JWT verification level.
12
+
13
+ - [Installation](#installation)
14
+ - [Usage](#usage)
15
+ - [Grape API](#grape-api)
16
+ - [Configuration](#configuration)
17
+ - [Authenticator](#authenticator)
18
+ - [Malformed token handling](#malformed-token-handling)
19
+ - [Failed authentication handling](#failed-authentication-handling)
20
+ - [RSA public key helper](#rsa-public-key-helper)
21
+ - [RSA public key location (URL)](#rsa-public-key-location-url)
22
+ - [RSA public key caching](#rsa-public-key-caching)
23
+ - [RSA public key cache expiration](#rsa-public-key-cache-expiration)
24
+ - [JWT instance helper](#jwt-instance-helper)
25
+ - [Issuer verification](#issuer-verification)
26
+ - [Beholder (audience) verification](#beholder-audience-verification)
27
+ - [Custom JWT verification options](#custom-jwt-verification-options)
28
+ - [Custom JWT verification key](#custom-jwt-verification-key)
29
+ - [Per-API configuration](#per-api-configuration)
30
+ - [Full RSA256 example](#full-rsa256-example)
31
+ - [Development](#development)
32
+ - [Contributing](#contributing)
33
+
34
+ ## Installation
35
+
36
+ Add this line to your application's Gemfile:
37
+
38
+ ```ruby
39
+ gem 'grape-jwt-authentication'
40
+ ```
41
+
42
+ And then execute:
43
+
44
+ ```bash
45
+ $ bundle
46
+ ```
47
+
48
+ Or install it yourself as:
49
+
50
+ ```bash
51
+ $ gem install grape-jwt-authentication
52
+ ```
53
+
54
+ ## Usage
55
+
56
+ ### Grape API
57
+
58
+ You can enable the JWT authentication on any Grape API you like. This includes
59
+ specific endpoints or a whole API. Just include the
60
+ `Grape::Jwt::Authentication` module and configure it the way you like.
61
+
62
+ ```ruby
63
+ module UserApi
64
+ class ApiV1 < Grape::API
65
+ # All your fancy Grape API stuff [..]
66
+ version 'v1', using: :path
67
+
68
+ # Enable JWT authentication on this API
69
+ include Grape::Jwt::Authentication
70
+ auth :jwt
71
+ end
72
+ end
73
+ ```
74
+
75
+ ### Configuration
76
+
77
+ This gem is quite customizable and flexible to fulfill your needs. You can make
78
+ use of some parts and leave other if you do not care about them. We are not
79
+ going to force the way how to verify JWT or work with them. Here comes a
80
+ overview of the configurations you can do.
81
+
82
+ #### Authenticator
83
+
84
+ The authenticator function which must be defined by the user to verify the
85
+ given JSON Web Token. Here comes all your logic to lookup the related user on
86
+ your database, the token claim verification and/or the token cryptographic
87
+ signing. The function must return true or false to indicate the validity of the
88
+ token.
89
+
90
+ ```ruby
91
+ Grape::Jwt::Authentication.configure do |conf|
92
+ conf.authenticator = proc do |token|
93
+ # Verify the token the way you like. (true, false)
94
+ end
95
+ end
96
+ ```
97
+
98
+ #### Malformed token handling
99
+
100
+ Whenever the given value on the `Authorization` header is not a valid Bearer
101
+ authentication scheme or the token itself is not a valid JSON Web Token, this
102
+ user defined function will be called. You can add custom handling of this
103
+ situations, like responding a different HTTP status code, or a more detailed
104
+ response body. By default the Rack stack will be interrupted and a response
105
+ with the `400 Bad Request` status code will be send to the client. The raw
106
+ token (value of the `Authorization` header) and the Rack app will be injected
107
+ to your function for maximum flexibility.
108
+
109
+ ```ruby
110
+ Grape::Jwt::Authentication.configure do |conf|
111
+ conf.malformed_auth_handler = proc do |raw_token, app|
112
+ # Do your own error handling. (Rack interface)
113
+ end
114
+ end
115
+ ```
116
+
117
+ #### Failed authentication handling
118
+
119
+ When the client sends a corrected formatted JSON Web Token with the Bearer
120
+ authentication scheme within the `Authorization` header and your authenticator
121
+ fails for some reason (token claims, wrong audience, bad subject, expired
122
+ token, wrong cryptographic signing etc), this function is called to handle the
123
+ bad authentication. By default the Rack stack will be interrupted and a
124
+ response with the `401 Unauthorized` status code will be send to the client.
125
+ You can customize this the way you like and send different error codes, or
126
+ handle the error completely different. The parsed JSON Web Token and the Rack
127
+ app will be injected to your function to allow any customized error handling.
128
+
129
+ ```ruby
130
+ Grape::Jwt::Authentication.configure do |conf|
131
+ conf.failed_auth_handler = proc do |token, app|
132
+ # Do your own error handling. (Rack interface)
133
+ end
134
+ end
135
+ ```
136
+
137
+ #### RSA public key helper
138
+
139
+ We provide a straightforward solution to deal with the provision of RSA public
140
+ keys. Somethimes you want to distribute them by file to each machine and have
141
+ a local access, and somethimes you provide an endpoint on your identity
142
+ provider to fetch the RSA public key via HTTP/HTTPS. The `RsaPublicKey` class
143
+ helps you to fulfill this task easily.
144
+
145
+ **Heads up!** You can skip this if you do not care about RSA verification or
146
+ have your own mechanism.
147
+
148
+ ```ruby
149
+ # Get your public key, by using the global configuration
150
+ public_key = Grape::Jwt::Authentication::RsaPublicKey.fetch
151
+ # => OpenSSL::PKey::RSA
152
+
153
+ # Using a local configuration
154
+ fetcher = Grape::Jwt::Authentication::RsaPublicKey.instance
155
+ fetcher.url = 'https://your.identity.provider/rsa_public_key'
156
+ public_key = fetcher.fetch
157
+ # => OpenSSL::PKey::RSA
158
+ ```
159
+
160
+ The following examples show you how to configure the
161
+ `Grape::Jwt::Authentication::RsaPublicKey` class the global way. This is useful
162
+ for a shared initializer place.
163
+
164
+ ##### RSA public key location (URL)
165
+
166
+ Whenever you want to use the `RsaPublicKey` class you configure the default URL
167
+ on the singleton instance, or use the gem configure method and set it up
168
+ accordingly. We allow the fetch of the public key from a remote server
169
+ (HTTP/HTTPS) or from a local file which is accessible by the ruby process.
170
+ Specify the URL or the local path here. Not specified by default.
171
+
172
+ ```ruby
173
+ Grape::Jwt::Authentication.configure do |conf|
174
+ # Local file
175
+ conf.rsa_public_key_url = '/tmp/jwt_rsa.pub'
176
+ # Remote URL
177
+ conf.rsa_public_key_url = 'https://your.identity.provider/rsa_public_key'
178
+ end
179
+ ```
180
+
181
+ ##### RSA public key caching
182
+
183
+ You can configure the `RsaPublickey` class to enable/disable caching. For a
184
+ remote public key location it is handy to cache the result for some time to
185
+ keep the traffic low to the resource server. For a local file you can skip
186
+ this. Disabled by default.
187
+
188
+ ```ruby
189
+ Grape::Jwt::Authentication.configure do |conf|
190
+ conf.rsa_public_key_caching = true
191
+ end
192
+ ```
193
+
194
+ ##### RSA public key cache expiration
195
+
196
+ When you make use of the cache of the `RsaPublicKey` class you can fine tune
197
+ the expiration time. The RSA public key from your identity
198
+ provider should not change this frequent, so a cache for at least one hour is
199
+ fine. You should not set it lower than one minute. Keep this setting in mind
200
+ when you change keys. Your infrastructure could be inoperable for this
201
+ configured time. One hour by default.
202
+
203
+ ```ruby
204
+ Grape::Jwt::Authentication.configure do |conf|
205
+ conf.rsa_public_key_expiration = 1.hour
206
+ end
207
+ ```
208
+
209
+ #### JWT instance helper
210
+
211
+ We ship a little wrapper class to ease the validation of JSON Web Tokens with
212
+ the help of the great [ruby-jwt](https://github.com/jwt/ruby-jwt) library. This
213
+ wrapper class provides some helpers like `#access_token?`, `#refresh_token?` or
214
+ `#expires_at` which returns a ActiveSupport time-zoned representation of the
215
+ token expiration timestamp. It is initially opinionated to RSA verification,
216
+ but can be tuned to verify HMAC or ECDSA signed tokens. It integrated well with
217
+ the `RsaPublicKey` fetcher class. (by default)
218
+
219
+ **Heads up!** You can skip this if you have your own JWT verification mechanism.
220
+
221
+ ```ruby
222
+ # A raw JWT (no signing, payload: {test: true})
223
+ raw_token = 'eyJ0eXAiOiJKV1QifQ.eyJ0ZXN0Ijp0cnVlfQ.'
224
+
225
+ # Parse the raw token and create a instance of it
226
+ token = Grape::Jwt::Authentication::Jwt.new(raw_token)
227
+
228
+ # Access the payload easily (recursive-open-struct)
229
+ token.payload.test
230
+ # => true
231
+
232
+ # Validate the token (we assume you configured the verification key, an/or
233
+ # you own custom JWT verification options here)
234
+ token.valid?
235
+ # => true
236
+ ```
237
+
238
+ The following examples show you how to configure the
239
+ `Grape::Jwt::Authentication::Jwt` class the global way. This is useful for a
240
+ shared initializer place.
241
+
242
+ ##### Issuer verification
243
+
244
+ The JSON Web Token issuer which should be used for verification. When `nil` we
245
+ also turn off the verification by default. (See the default JWT options)
246
+
247
+ ```ruby
248
+ Grape::Jwt::Authentication.configure do |conf|
249
+ conf.jwt_issuer = 'your-identity-provider'
250
+ end
251
+ ```
252
+
253
+ ##### Beholder (audience) verification
254
+
255
+ The resource server (namely the one which configures this right now)
256
+ which MUST be present on the JSON Web Token audience claim. When `nil` we
257
+ also turn off the verification by default. (See the default JWT options)
258
+
259
+ ```ruby
260
+ Grape::Jwt::Authentication.configure do |conf|
261
+ conf.jwt_beholder = 'your-resource-server'
262
+ end
263
+ ```
264
+
265
+ ##### Custom JWT verification options
266
+
267
+ You can configure a different JSON Web Token verification option hash if your
268
+ algorithm differs or you want some extra/different options. Just watch out
269
+ that you have to pass a proc to this configuration property. On the
270
+ `Grape::Jwt::Authentication::Jwt` class it has to be a simple hash. The default
271
+ is here the `RS256` algorithm with enabled expiration check, and issuer+audience
272
+ check when the `jwt_issuer` / `jwt_beholder` are configured accordingly.
273
+
274
+ ```ruby
275
+ Grape::Jwt::Authentication.configure do |conf|
276
+ conf.jwt_options = proc do
277
+ # See: https://github.com/jwt/ruby-jwt
278
+ { algorithm: 'HS256' }
279
+ end
280
+ end
281
+ ```
282
+
283
+ ##### Custom JWT verification key
284
+
285
+ You can configure your own verification key on the `Jwt` wrapper class. This
286
+ way you can pass your HMAC secret or your ECDSA public key to the JSON Web
287
+ Token validation method. Here you need to pass a proc, on the
288
+ `Grape::Jwt::Authentication::Jwt` class it has to be a scalar value. By default
289
+ we use the `RsaPublicKey` class to retrieve the RSA public key.
290
+
291
+ ```ruby
292
+ Grape::Jwt::Authentication.configure do |conf|
293
+ conf.jwt_verification_key = proc do
294
+ # Retrieve your verification key (RSA, ECDSA, HMAC secret)
295
+ # the way you like, and pass it back here.
296
+ end
297
+ end
298
+ ```
299
+
300
+ ### Per-API configuration
301
+
302
+ Imagine the migration of your API (say v2) and also the JSON Web Token payload
303
+ changes in a way you need to handle. Maybe you want to be more strict on
304
+ version 2 than on your old version 1. For this you can make use of the local
305
+ configuration of the JWT authenticator, on your specific Grape API declaration.
306
+ Here comes an example usage:
307
+
308
+ ```ruby
309
+ module UserApi
310
+ class ApiV2 < Grape::API
311
+ v2_auth_malformed = proc { |raw_token, app| [400, {}, ['Malformed!']] }
312
+ v2_auth_failed = proc { |token, app| [401, {}, ['Go away!']] }
313
+
314
+ # Enable JWT authentication on this API
315
+ include Grape::Jwt::Authentication
316
+ auth(:jwt, malformed: v2_auth_malformed,
317
+ failed: v2_auth_failed) do |token|
318
+ # Your new stricter v2 authenticator.
319
+ false
320
+ end
321
+ end
322
+ end
323
+ ```
324
+
325
+ ### Full RSA256 example
326
+
327
+ Here comes a full example of the opinionated `RSA256` algorithm usage with a
328
+ remote RSA public key location, enabled caching and a full token payload
329
+ verification.
330
+
331
+ ```ruby
332
+ # On an initializer ..
333
+ Grape::Jwt::Authentication.configure do |conf|
334
+ # The remote RSA public key location and enabled caching to limit the
335
+ # traffic on the remote server.
336
+ conf.rsa_public_key_url = 'https://your.identity.provider/rsa_public_key'
337
+ conf.rsa_public_key_caching = true
338
+ conf.rsa_public_key_expiration = 10.minutes
339
+
340
+ # Configure the JWT wrapper.
341
+ conf.jwt_issuer = 'The Identity Provider'
342
+ conf.jwt_beholder = 'example-api'
343
+
344
+ # Let Grape handle the malformed error with correct response formatting.
345
+ # (XML, JSON)
346
+ conf.malformed_auth_handler = proc do |raw_token, app|
347
+ raise ArgumentError, 'Authorization header is malformed.'
348
+ end
349
+
350
+ # The same procedure for failed verifications. (XML, JSON formatting handled
351
+ # external by Grape)
352
+ conf.failed_auth_handler = proc do |token, app|
353
+ raise ArgumentError, 'Access denied.'
354
+ end
355
+
356
+ # Custom verification logic.
357
+ conf.authenticator = proc do |token|
358
+ # Parse and instantiate a JWT verification instance
359
+ jwt = Grape::Jwt::Authentication::Jwt.new(token)
360
+
361
+ # We just allow valid access tokens
362
+ jwt.access_token? && jwt.valid?
363
+ end
364
+ end
365
+
366
+ # On your Grape API ..
367
+ module UserApi
368
+ class ApiV1 < Grape::API
369
+ # Enable JWT authentication on this API
370
+ include Grape::Jwt::Authentication
371
+ auth :jwt
372
+ end
373
+ end
374
+ ```
375
+
376
+ ## Development
377
+
378
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
379
+ `rake spec` to run the tests. You can also run `bin/console` for an interactive
380
+ prompt that will allow you to experiment.
381
+
382
+ To install this gem onto your local machine, run `bundle exec rake install`. To
383
+ release a new version, update the version number in `version.rb`, and then run
384
+ `bundle exec rake release`, which will create a git tag for the version, push
385
+ git commits and tags, and push the `.gem` file to
386
+ [rubygems.org](https://rubygems.org).
387
+
388
+ ## Contributing
389
+
390
+ Bug reports and pull requests are welcome on GitHub at
391
+ https://github.com/hausgold/grape-jwt-authentication.