api_guard 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +597 -0
  4. data/Rakefile +24 -0
  5. data/app/controllers/api_guard/application_controller.rb +7 -0
  6. data/app/controllers/api_guard/authentication_controller.rb +29 -0
  7. data/app/controllers/api_guard/passwords_controller.rb +27 -0
  8. data/app/controllers/api_guard/registration_controller.rb +28 -0
  9. data/app/controllers/api_guard/tokens_controller.rb +27 -0
  10. data/app/models/api_guard/application_record.rb +5 -0
  11. data/app/views/layouts/api_guard/application.html.erb +14 -0
  12. data/config/routes.rb +4 -0
  13. data/lib/api_guard.rb +32 -0
  14. data/lib/api_guard/engine.rb +15 -0
  15. data/lib/api_guard/jwt_auth/authentication.rb +83 -0
  16. data/lib/api_guard/jwt_auth/blacklist_token.rb +31 -0
  17. data/lib/api_guard/jwt_auth/json_web_token.rb +66 -0
  18. data/lib/api_guard/jwt_auth/refresh_jwt_token.rb +42 -0
  19. data/lib/api_guard/models/concerns.rb +25 -0
  20. data/lib/api_guard/modules.rb +24 -0
  21. data/lib/api_guard/resource_mapper.rb +41 -0
  22. data/lib/api_guard/response_formatters/renderer.rb +19 -0
  23. data/lib/api_guard/route_mapper.rb +81 -0
  24. data/lib/api_guard/test/controller_helper.rb +11 -0
  25. data/lib/api_guard/version.rb +3 -0
  26. data/lib/generators/api_guard/controllers/USAGE +11 -0
  27. data/lib/generators/api_guard/controllers/controllers_generator.rb +23 -0
  28. data/lib/generators/api_guard/controllers/templates/authentication_controller.rb +27 -0
  29. data/lib/generators/api_guard/controllers/templates/passwords_controller.rb +25 -0
  30. data/lib/generators/api_guard/controllers/templates/registration_controller.rb +26 -0
  31. data/lib/generators/api_guard/controllers/templates/tokens_controller.rb +25 -0
  32. data/lib/generators/api_guard/initializer/USAGE +8 -0
  33. data/lib/generators/api_guard/initializer/initializer_generator.rb +11 -0
  34. data/lib/generators/api_guard/initializer/templates/initializer.rb +13 -0
  35. metadata +217 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc34f3bf30f6d777d1350a7a66f30db8e5dd848c
4
+ data.tar.gz: fefe25e711ccb0fe99433fe321734b1abb850b1d
5
+ SHA512:
6
+ metadata.gz: 36553d07a9491c368be3790b53b991b3b9f1519faaea1cb93023cfb0436e51a7c491c5eba499b38abcce48731a851c5f4a99fce1830f259c9bf7bd88d303aacb
7
+ data.tar.gz: c00a3c77306a8214af71cb16270c59f7c7e441d9d1f885cf80e776a1be124c587a75b9b0f601bf224d8502568a55b0d5bea4eacf6ca0bf658bf87de99f02a33d
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018 Gokul Murali
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,597 @@
1
+ # API Guard
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/api_guard.svg)](https://badge.fury.io/rb/api_guard)
4
+ [![Build Status](https://travis-ci.org/Gokul595/api_guard.svg?branch=master)](https://travis-ci.org/Gokul595/api_guard)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/ced3e74a26a66ed915cb/maintainability)](https://codeclimate.com/github/Gokul595/api_guard/maintainability)
6
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/ced3e74a26a66ed915cb/test_coverage)](https://codeclimate.com/github/Gokul595/api_guard/test_coverage)
7
+
8
+
9
+ [JSON Web Token (JWT)](https://jwt.io/) based authentication solution with token refreshing & blacklisting for APIs
10
+ built on Rails.
11
+
12
+ This is built using [Ruby JWT](https://github.com/jwt/ruby-jwt) gem. Currently API Guard supports only HS256 algorithm
13
+ for cryptographic signing.
14
+
15
+ ## Table of Contents
16
+
17
+ * [Installation](#installation)
18
+ * [Getting Started](#getting-started)
19
+ * [Creating User model](#creating-user-model)
20
+ * [Configuring Routes](#configuring-routes)
21
+ * [Registration](#registration)
22
+ * [Sign In (Getting JWT access token)](#sign-in-getting-jwt-access-token)
23
+ * [Authenticate API Request](#authenticate-api-request)
24
+ * [Refresh access token](#refresh-access-token)
25
+ * [Change password](#change-password)
26
+ * [Sign out](#sign-out)
27
+ * [Delete Account](#delete-account)
28
+ * [Configuration](#configuration)
29
+ * [Default configuration](#default-configuration)
30
+ * [Access token validity](#access-token-validity)
31
+ * [Access token signing secret](#access-token-signing-secret)
32
+ * [Invalidate tokens on password change](#invalidate-tokens-on-password-change)
33
+ * [Token refreshing](#token-refreshing)
34
+ * [Token blacklisting](#token-blacklisting)
35
+ * [Overriding defaults](#overriding-defaults)
36
+ * [Controllers](#controllers)
37
+ * [Routes](#routes)
38
+ * [Testing](#testing)
39
+ * [Contributing](#contributing)
40
+ * [License](#license)
41
+
42
+
43
+ ## Installation
44
+ Add this line to your application's Gemfile:
45
+
46
+ ```ruby
47
+ gem 'api_guard'
48
+ ```
49
+
50
+ And then execute in your terminal:
51
+ ```bash
52
+ $ bundle install
53
+ ```
54
+
55
+ Or install it yourself as:
56
+ ```bash
57
+ $ gem install api_guard
58
+ ```
59
+
60
+ ## Getting Started
61
+
62
+ Below steps are provided assuming the model in `User`.
63
+
64
+ ### Creating User model
65
+
66
+ Create a model for User with below command
67
+
68
+ ```bash
69
+ $ rails generate model user name:string email:string:uniq password_digest:string
70
+ ```
71
+
72
+ Then, run migration to create the `users` table
73
+
74
+ ```bash
75
+ $ rails db:migrate
76
+ ```
77
+
78
+ Add [has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password)
79
+ in `User` model for password authentication
80
+
81
+ ```ruby
82
+ class User < ApplicationRecord
83
+ has_secure_password
84
+ end
85
+ ```
86
+
87
+ Then, add `bcrypt` gem in your Gemfile which is used by
88
+ [has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password)
89
+ for encrypting password and authentication
90
+
91
+ ```ruby
92
+ gem 'bcrypt', '~> 3.1.7'
93
+ ```
94
+
95
+ And then execute in your terminal:
96
+
97
+ ```bash
98
+ $ bundle install
99
+ ```
100
+
101
+ ### Configuring Routes
102
+
103
+ Add this line to the application routes (`config/routes.rb`) file:
104
+
105
+ ```ruby
106
+ api_guard_routes for: 'users'
107
+ ```
108
+
109
+ This will generate default routes such as sign up, sign in, sign out, token refresh, password change for User.
110
+
111
+ ### Registration
112
+
113
+ This will create an user and responds with access token, refresh token and access token expiry in the response header.
114
+
115
+ Example request:
116
+
117
+ ```
118
+ # URL
119
+ POST "/users/sign_up"
120
+
121
+ # Request body
122
+ {
123
+ "email": "user@apiguard.com",
124
+ "password": "api_password",
125
+ "password_confirmation": "api_password"
126
+ }
127
+ ```
128
+
129
+ Example response body:
130
+
131
+ ```json
132
+ {
133
+ "status": "success",
134
+ "message": "Signed up successfully"
135
+ }
136
+ ```
137
+
138
+ Example response headers:
139
+
140
+ ```
141
+ Access-Token: eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NDY3MDgwMjAsImlhdCI6MTU0NjcwNjIyMH0.F_JM7fUcKEAq9ZxXMxNb3Os-WeY-tuRYQnKXr_bWo5E
142
+ Refresh-Token: Iy9s0S4Lf7Xh9MbFFBdxkw
143
+ Expire-At: 1546708020
144
+ ```
145
+
146
+ The access token will only be valid till the expiry time. After the expiry you need to
147
+ [refresh the token](#refresh-access-token) and get new access token and refresh token.
148
+
149
+ You can customize the parameters of this API by [overriding the controller](#controllers) code if needed.
150
+
151
+ ### Sign In (Getting JWT access token)
152
+
153
+ This will authenticate the user with email and password and respond with access token, refresh token and access token
154
+ expiry in the response header.
155
+
156
+ >To make this work, the resource model (User) should have an `authenticate` method as available in
157
+ [has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password).
158
+ You can use [has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password)
159
+ or your own logic to authenticate the user in `authenticate` method.
160
+
161
+ Example request:
162
+
163
+ ```
164
+ # URL
165
+ POST "/users/sign_in"
166
+
167
+ # Request body
168
+ {
169
+ "email": "user@apiguard.com",
170
+ "password": "api_password"
171
+ }
172
+ ```
173
+
174
+ Example response body:
175
+
176
+ ```json
177
+ {
178
+ "status": "success",
179
+ "message": "Signed in successfully"
180
+ }
181
+ ```
182
+
183
+ Example response headers:
184
+
185
+ The response headers for this request will be same as [registration API](#registration).
186
+
187
+ You can customize the parameters of this API by [overriding the controller](#controllers) code if needed.
188
+
189
+ ### Authenticate API Request
190
+
191
+ To authenticate the API request just add this before_action in the controller:
192
+
193
+ ```ruby
194
+ before_action :authenticate_and_set_user
195
+ ```
196
+
197
+ Send the access token got in sign in API in the Authorization header in the API request as below.
198
+ Also, make sure you add "Bearer" before the access token in the header value.
199
+
200
+ ```
201
+ Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NDY3MDgwMjAsImlhdCI6MTU0NjcwNjIyMH0.F_JM7fUcKEAq9ZxXMxNb3Os-WeY-tuRYQnKXr_bWo5E
202
+ ```
203
+
204
+ Then, you can get the current authenticated user using below method:
205
+
206
+ ```ruby
207
+ current_user
208
+ ```
209
+
210
+ and also, using below instance variable:
211
+
212
+ ```ruby
213
+ @current_user
214
+ ```
215
+
216
+ >**Note:** Replace `_user` with your model name if your model is not User.
217
+
218
+ ### Refresh access token
219
+
220
+ This will work only if token refreshing configured for the resource.
221
+ Please see [token refreshing](#token-refreshing) for details about configuring token refreshing.
222
+
223
+ Once the access token expires it won't work and the `authenticate_and_set_user` method used in before_action in
224
+ controller will respond with 401 (Unauthenticated).
225
+
226
+ To refresh the expired access token and get new access and refresh token you can use this request
227
+ with both access token and request token (which you got in sign in API) in the request header.
228
+
229
+ Example request:
230
+
231
+ ```
232
+ # URL
233
+ POST "/users/tokens"
234
+
235
+ # Request header
236
+ Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NDY3MDgwMjAsImlhdCI6MTU0NjcwNjIyMH0.F_JM7fUcKEAq9ZxXMxNb3Os-WeY-tuRYQnKXr_bWo5E
237
+ Refresh-Token: Iy9s0S4Lf7Xh9MbFFBdxkw
238
+ ```
239
+
240
+ Example response body:
241
+
242
+ ```json
243
+ {
244
+ "status": "success",
245
+ "message": "Token refreshed successfully"
246
+ }
247
+ ```
248
+
249
+ Example response headers:
250
+
251
+ The response headers for this request will be same as [registration API](#registration).
252
+
253
+ ### Change password
254
+
255
+ To change password of an user you can use this request with the access token in the header and new
256
+ password in the body.
257
+
258
+ By default, changing password will invalidate all old access tokens and refresh tokens generated for this user and
259
+ responds with new access token and refresh token.
260
+
261
+ Example request:
262
+
263
+ ```
264
+ # URL
265
+ PATCH "/users/passwords"
266
+
267
+ # Request header
268
+ Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NDY3MDgwMjAsImlhdCI6MTU0NjcwNjIyMH0.F_JM7fUcKEAq9ZxXMxNb3Os-WeY-tuRYQnKXr_bWo5E
269
+
270
+ # Request body
271
+ {
272
+ "password": "api_password_new",
273
+ "password_confirmation": "api_password_new"
274
+ }
275
+ ```
276
+
277
+ Example response body:
278
+
279
+ ```json
280
+ {
281
+ "status": "success",
282
+ "message": "Password changed successfully"
283
+ }
284
+ ```
285
+
286
+ Example response headers:
287
+
288
+ The response headers for this request will be same as [registration API](#registration).
289
+
290
+ ### Sign out
291
+
292
+ You can use this request to sign out an user. This will blacklist the current access token from future use if
293
+ [token blacklisting](#token-blacklisting) configured.
294
+
295
+ Example request:
296
+
297
+ ```
298
+ # URL
299
+ DELETE "/users/sign_out"
300
+
301
+ # Request header
302
+ Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NDY3MDgwMjAsImlhdCI6MTU0NjcwNjIyMH0.F_JM7fUcKEAq9ZxXMxNb3Os-WeY-tuRYQnKXr_bWo5E
303
+ ```
304
+
305
+ Example response:
306
+
307
+ ```json
308
+ {
309
+ "status": "success",
310
+ "message": "Signed out successfully"
311
+ }
312
+ ```
313
+
314
+ ### Delete account
315
+
316
+ You can use this request to delete an user. This will delete the user and its associated refresh tokens.
317
+
318
+ Example request:
319
+
320
+ ```
321
+ # URL
322
+ DELETE "/users/delete"
323
+
324
+ # Request header
325
+ Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NDY3MDgwMjAsImlhdCI6MTU0NjcwNjIyMH0.F_JM7fUcKEAq9ZxXMxNb3Os-WeY-tuRYQnKXr_bWo5E
326
+ ```
327
+
328
+ Example response:
329
+
330
+ ```json
331
+ {
332
+ "status": "success",
333
+ "message": "Account deleted successfully"
334
+ }
335
+ ```
336
+
337
+ ## Configuration
338
+
339
+ To configure the API Guard you need to first create an initializer using
340
+
341
+ ```bash
342
+ $ rails generate api_guard:initializer
343
+ ```
344
+
345
+ This will generate an initializer named **api_guard.rb** in your app **config/initializers** directory with default
346
+ configurations.
347
+
348
+ ### Default configuration
349
+
350
+ **config/initializers/api_guard.rb**
351
+
352
+ ```ruby
353
+ ApiGuard.setup do |config|
354
+ # Validity of the JWT access token
355
+ # Default: 1 day
356
+ config.token_validity = 1.day
357
+
358
+ # Secret key for signing (encoding & decoding) the JWT access token
359
+ # Default: 'secret_key_base' from Rails secrets
360
+ config.token_signing_secret = Rails.application.secrets.secret_key_base
361
+
362
+ # Invalidate old tokens on changing the password
363
+ # Default: false
364
+ config.invalidate_old_tokens_on_password_change = false
365
+ end
366
+ ```
367
+
368
+ ### Access token validity
369
+
370
+ By default, the validity of the JWT access token is 1 day from the creation. Override this by configuring `token_validity`
371
+
372
+ ```ruby
373
+ config.token_validity = 1.hour # Set one hour validity for access tokens
374
+ ```
375
+
376
+ On accessing the authenticated API with expired access token, API Guard will respond 401 (Unauthenticated) with message
377
+ "Access token expired".
378
+
379
+ ### Access token signing secret
380
+
381
+ By default, the `secret_key_base` from the Rails secrets will be used for signing (encoding & decoding) the JWT access token.
382
+ Override this by configuring `token_signing_secret`
383
+
384
+ ```ruby
385
+ config.token_signing_secret = 'my_signing_secret'
386
+ ```
387
+
388
+ ### Invalidate tokens on password change
389
+
390
+ By default, API Guard will not invalidate old JWT access tokens on changing password. If you need, you can enable it by
391
+ configuring `invalidate_old_tokens_on_password_change` to `true`.
392
+
393
+ >**Note:** To make this work, a column named `token_issued_at` with datatype `datetime` is needed in the resource table.
394
+
395
+ ```ruby
396
+ config.invalidate_old_tokens_on_password_change = true
397
+ ```
398
+
399
+ If your app allows multiple logins then, you must set this value to `true` so that, this prevent access for all logins
400
+ (access tokens) on changing the password.
401
+
402
+ ### Token refreshing
403
+
404
+ To include token refreshing in your application you need to create a table to store the refresh tokens.
405
+
406
+ Use below command to create a model `RefeshToken` with columns to store the token and the user reference
407
+
408
+ ```bash
409
+ $ rails generate model refresh_token token:string:uniq user:references
410
+ ```
411
+
412
+ Then, run migration to create the `refresh_tokens` table
413
+
414
+ ```bash
415
+ $ rails db:migrate
416
+ ```
417
+
418
+ >**Note:** Replace `user` in the above command with your model name if your model is not User.
419
+
420
+ After creating model and table for refresh token configure the association in the resource model using
421
+ `api_guard_associations` method
422
+
423
+ ```ruby
424
+ class User < ApplicationRecord
425
+ api_guard_associations refresh_token: 'refresh_tokens'
426
+ has_many :refresh_tokens, dependent: :delete_all
427
+ end
428
+ ```
429
+
430
+ If you also have token blacklisting enabled you need to specify both associations as below
431
+
432
+ ```ruby
433
+ api_guard_associations refresh_token: 'refresh_tokens', blacklisted_token: 'blacklisted_tokens'
434
+ ```
435
+
436
+ ### Token blacklisting
437
+
438
+ To include token blacklisting in your application you need to create a table to store the refresh tokens. This will be
439
+ used to blacklist a JWT access token from future use. The access token will be blacklisted on successful sign out of the
440
+ resource.
441
+
442
+ Use below command to create a model `RefeshToken` with columns to store the token and the user reference
443
+
444
+ ```bash
445
+ $ rails generate model blacklisted_token token:string user:references expire_at:datetime
446
+ ```
447
+
448
+ Then, run migration to create the `blacklisted_tokens` table
449
+
450
+ ```bash
451
+ $ rails db:migrate
452
+ ```
453
+
454
+ >**Note:** Replace `user` in the above command with your model name if your model is not User.
455
+
456
+ After creating model and table for blacklisted token configure the association in the resource model using
457
+ `api_guard_associations` method
458
+
459
+ ```ruby
460
+ class User < ApplicationRecord
461
+ api_guard_associations blacklisted_token: 'blacklisted_tokens'
462
+ has_many :blacklisted_tokens, dependent: :delete_all
463
+ end
464
+ ```
465
+
466
+ If you also have token refreshing enabled you need to specify both associations as below
467
+
468
+ ```ruby
469
+ api_guard_associations refresh_token: 'refresh_tokens', blacklisted_token: 'blacklisted_tokens'
470
+ ```
471
+
472
+ And, as this creates rows in `blacklisted_tokens` table you need to have a mechanism to delete the expired blacklisted
473
+ tokens to prevent this table from growing. One option is to have a CRON job to run a task daily that deletes the
474
+ blacklisted tokens that are expired i.e. `expire_at < DateTime.now`.
475
+
476
+ ## Overriding defaults
477
+
478
+ ### Controllers
479
+
480
+ You can override the default API Guard controllers and customize the code as your need by generating the controllers in
481
+ your app
482
+
483
+ ```bash
484
+ $ rails generate api_guard:controllers users
485
+ ```
486
+
487
+ In above command `users` is the scope of the controllers. If needed, you can replace `users` with your own scope.
488
+
489
+ This will generate all default controllers for `users` in the directory **app/controllers/users**.
490
+
491
+ Then, configure this controller in the routes
492
+
493
+ ```ruby
494
+ api_guard_routes for: 'users', controller: {
495
+ registration: 'users/registration',
496
+ authentication: 'users/authentication',
497
+ passwords: 'users/passwords',
498
+ tokens: 'users/tokens'
499
+ }
500
+ ```
501
+
502
+ You can also specify the controllers that you need to generate using `-c` or `--controllers` option.
503
+
504
+ ```bash
505
+ $ rails generate api_guard:controllers users -c registration authentication
506
+ ```
507
+
508
+ >**Available controllers:** registration, authentication, tokens, passwords
509
+
510
+ ### Routes
511
+
512
+ You can skip specific controller routes generated by API Guard
513
+
514
+ ```ruby
515
+ api_guard_routes for: 'users', except: [:registration]
516
+ ```
517
+
518
+ Above config will skip registration related API Guard controller routes for the resource user.
519
+
520
+
521
+ You can also specify only the controller routes you need,
522
+
523
+ ```ruby
524
+ api_guard_routes for: 'users', only: [:authentication]
525
+ ```
526
+
527
+ >**Available controllers:** registration, authentication, tokens, passwords
528
+
529
+ **Customizing the routes**
530
+
531
+ To customize the default routes generated by API Guard you can use `api_guard_scope` in the routes.
532
+
533
+ ```ruby
534
+ api_guard_routes for: 'users', except: [:registration]
535
+
536
+ api_guard_scope 'users' do
537
+ post 'account/create' => 'users/registration#create'
538
+ delete 'account/delete' => 'users/registration#destroy'
539
+ end
540
+ ```
541
+
542
+ Above configuration will replace default registration routes `users/sign_up` & `users/delete` with `account/create` &
543
+ `account/delete`
544
+
545
+ ## Testing
546
+
547
+ API Guard comes with helper for creating JWT access token and refresh token for the resource which you can use it for
548
+ testing the controllers of your application.
549
+
550
+ For using it include the helper in you test framework
551
+
552
+ **RSpec**
553
+
554
+ If you're using RSpec as your test framework then include the helper in **spec/rails_helper.rb** file
555
+
556
+ ```ruby
557
+ RSpec.configure do |config|
558
+ config.include ApiGuard::Test::ControllerHelper
559
+ end
560
+ ```
561
+
562
+ **Minitest**
563
+
564
+ If you're using Minitest as your test framework then include the helper in your test file
565
+
566
+ ```ruby
567
+ include ApiGuard::Test::ControllerHelper
568
+ ```
569
+
570
+ After including the helper, you can use this method to create the JWT access token and refresh token for the resource
571
+
572
+ ```ruby
573
+ jwt_and_refresh_token(user, 'user')
574
+ ```
575
+
576
+ Where the first argument is the resource(User) object and the second argument is the resource name which is `user`.
577
+
578
+ This method will return two values which is access token and refresh token.
579
+
580
+ If you need expired JWT access token for testing you can pass the third optional argument value as `true`
581
+
582
+ ```ruby
583
+ jwt_and_refresh_token(user, 'user', true)
584
+ ```
585
+
586
+ Then, you can set the access token and refresh token in appropriate request header on each test request.
587
+
588
+ ## Contributing
589
+
590
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Gokul595/api_guard.
591
+ This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to
592
+ the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
593
+
594
+ ## License
595
+
596
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
597
+