auth_rails 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ # CLI to generate Migration
2
+
3
+ This CLI always need to provide a strategy option to know which migration file should be created.
4
+
5
+ ## Default Option
6
+
7
+ ```sh
8
+ rails g auth_rails:migration --strategy allowed_token
9
+ ```
10
+
11
+ This will create a migration file for `AllowedToken` model.
12
+
13
+ ```rb
14
+ # frozen_string_literal: true
15
+
16
+ class CreateAllowedTokens < ActiveRecord::Migration[7.1]
17
+ def change
18
+ create_table :allowed_tokens do |t|
19
+ t.string :jti, null: false
20
+ t.string :aud
21
+ t.datetime :exp, null: false
22
+
23
+ t.timestamps
24
+
25
+ t.references :user, foreign_key: { on_delete: :cascade }, null: false
26
+
27
+ t.index %i[jti aud]
28
+ end
29
+ end
30
+ end
31
+ ```
32
+
33
+ ## Model Option
34
+
35
+ ```sh
36
+ rails g auth_rails:migration --strategy allowed_token --model CustomUser
37
+ ```
38
+
39
+ This will create a migration file for `AllowedToken` model and add reference with `CustomUser`.
40
+
41
+ ```rb
42
+ # frozen_string_literal: true
43
+
44
+ class CreateAllowedTokens < ActiveRecord::Migration[7.1]
45
+ def change
46
+ create_table :allowed_tokens do |t|
47
+ t.string :jti, null: false
48
+ t.string :aud
49
+ t.datetime :exp, null: false
50
+
51
+ t.timestamps
52
+
53
+ t.references :custom_user, foreign_key: { on_delete: :cascade }, null: false
54
+
55
+ t.index %i[jti aud]
56
+ end
57
+ end
58
+ end
59
+ ```
@@ -0,0 +1,33 @@
1
+ # Custom retrieve resource
2
+
3
+ Sometimes, your logic to retrieve user is too complex. It is not simple `User.find_by(email: identifier)`.
4
+
5
+ ```rb
6
+ # frozen_string_literal: true
7
+
8
+ Rails.application.config.to_prepare do
9
+ AuthRails.configure do |config|
10
+ config.resource_class = User
11
+ config.identifier_name = :username
12
+ config.dig_params = ->(params) { params[:identifier] }
13
+
14
+ config.retrieve_resource = lambda { |identifier|
15
+ User.where(email: identifier)
16
+ .or(User.where(username: identifier))
17
+ .first
18
+ }
19
+ end
20
+ end
21
+ ```
22
+
23
+ ## config.identifier_name
24
+
25
+ This will be used to set to `sub` of JWT's `payload`.
26
+
27
+ ## config.dig_params
28
+
29
+ To extract `identifier` for the `retrieve_resource` config.
30
+
31
+ ## config.retrieve_resource
32
+
33
+ This is where you define how to get your resource to do the sign in.
@@ -0,0 +1,16 @@
1
+ # Custom your own identifier for your model
2
+
3
+ My model does not use `email` as its `identifier`, how to make AuthRails works with my model?
4
+
5
+ Tell AuthRails what it is.
6
+
7
+ ```rb
8
+ # frozen_string_literal: true
9
+
10
+ Rails.application.config.to_prepare do
11
+ AuthRails.configure do |config|
12
+ config.resource_class = User
13
+ config.identifier_name = :username
14
+ end
15
+ end
16
+ ```
@@ -0,0 +1,14 @@
1
+ # Use your own validation password
2
+
3
+ The method `authenticate` of `has_secure_password` is not good for you? Then make your own validation password.
4
+
5
+ ```rb
6
+ # frozen_string_literal: true
7
+
8
+ Rails.application.config.to_prepare do
9
+ AuthRails.configure do |config|
10
+ config.resource_class = User
11
+ config.authenticate = ->(resource, password) { resource.password == password }
12
+ end
13
+ end
14
+ ```
@@ -0,0 +1,63 @@
1
+ # Response your own data structure
2
+
3
+ Not happy with the default response? Do not worry, you can override it easily.
4
+
5
+ ## Sign In Response
6
+
7
+ To custom your sign in response data structure, you should override the method `respond_to_create`.
8
+
9
+ ```rb
10
+ # frozen_string_literal: true
11
+
12
+ module Api
13
+ class AuthController < AuthRails::Api::AuthController
14
+ private
15
+
16
+ def respond_to_create(data)
17
+ render json: {
18
+ profile: CurrentAuth.user,
19
+ tokens: {
20
+ auth_token: data[:access_token],
21
+ refresh_token: data[:refresh_token]
22
+ }
23
+ }
24
+ end
25
+ end
26
+ end
27
+ ```
28
+
29
+ If your response for refresh token action is the same, make this as its alias.
30
+
31
+ ```rb
32
+ alias respond_to_refresh respond_to_create
33
+ ```
34
+
35
+ ## Refresh Response
36
+
37
+ To custom your refresh action response data structure, you should override the method `respond_to_refresh`.
38
+
39
+ ```rb
40
+ # frozen_string_literal: true
41
+
42
+ module Api
43
+ class AuthController < AuthRails::Api::AuthController
44
+ private
45
+
46
+ def respond_to_refresh(data)
47
+ render json: {
48
+ profile: CurrentAuth.user,
49
+ tokens: {
50
+ auth_token: data[:access_token],
51
+ refresh_token: data[:refresh_token]
52
+ }
53
+ }
54
+ end
55
+ end
56
+ end
57
+ ```
58
+
59
+ In case your sign in action's response is the same, make this as its alias.
60
+
61
+ ```rb
62
+ alias respond_to_create respond_to_refresh
63
+ ```
@@ -0,0 +1,33 @@
1
+ # Use your own strategy
2
+
3
+ AuthRails provides a base strategy that has two methods: `retrieve_resource` and `gen_token`.
4
+
5
+ In your project, you may need to handle `refresh_token` in another approach instead of `allowed_token`. You can inherit base strategy and override those two methods to do your own strategy.
6
+
7
+ ```rb
8
+ # frozen_string_literal: true
9
+
10
+ class YourOwnStrategy < AuthRails::Strategies::BaseStrategy
11
+ class << self
12
+ def retrieve_resource(payload:)
13
+ # handle payload and retrieve the user using that payload
14
+ end
15
+
16
+ def gen_token(resource:, payload:, exp: nil, secret_key: nil, algorithm: nil, jti: nil)
17
+ # handle how to generate refresh_token
18
+ end
19
+ end
20
+ end
21
+ ```
22
+
23
+ Next, add this class to the configuration.
24
+
25
+ ```rb
26
+ # frozen_string_literal: true
27
+
28
+ AuthRails.configure do |config|
29
+ config.jwt do |jwt|
30
+ jwt.strategy = YourOwnStrategy
31
+ end
32
+ end
33
+ ```
data/docs/src/index.md ADDED
@@ -0,0 +1,14 @@
1
+ ---
2
+ layout: home
3
+
4
+ hero:
5
+ name: AuthRails
6
+ tagline: Simple authentication for Rails
7
+ actions:
8
+ - theme: brand
9
+ text: Get Started
10
+ link: /introduction/getting-started
11
+ - theme: alt
12
+ text: View on GitHub
13
+ link: https://github.com/zgid123/auth_rails
14
+ ---
@@ -0,0 +1,111 @@
1
+ # Getting Started
2
+
3
+ ## Installation
4
+
5
+ ```rb
6
+ gem 'auth_rails'
7
+ ```
8
+
9
+ ## Configuration
10
+
11
+ AuthRails provides a rake task to generate a configuration file.
12
+
13
+ ```sh
14
+ rails g auth_rails
15
+ ```
16
+
17
+ It will create a file `config/initializers/auth_rails.rb` with a default configuration.
18
+
19
+ ```rb
20
+ # frozen_string_literal: true
21
+
22
+ AuthRails.configure do |config|
23
+ config.jwt do |jwt|
24
+ jwt.access_token do |access_token|
25
+ access_token.exp = 1.hour.since
26
+ access_token.secret_key = ENV.fetch('JWT_SECRET', '')
27
+ end
28
+
29
+ # jwt.strategy = AuthRails::Strategies::AllowedTokenStrategy
30
+
31
+ # if you wanna use refresh token
32
+ # uncomment those lines below
33
+ # jwt.refresh_token do |refresh_token|
34
+ # refresh_token.http_only = true
35
+ # refresh_token.exp = 1.year.since
36
+ # refresh_token.algorithm = 'HS256'
37
+ # refresh_token.cookie_key = :ref_tok
38
+ # refresh_token.secret_key = ENV.fetch('JWT_SECRET', '')
39
+ # end
40
+ end
41
+ end
42
+
43
+ Rails.application.config.to_prepare do
44
+ AuthRails.configure do |config|
45
+ config.resource_class = User
46
+
47
+ # if you wanna use custom error classes
48
+ # uncomment code below
49
+ # config.error_class = AuthError
50
+ end
51
+ end
52
+ ```
53
+
54
+ > [!NOTE]
55
+ > [Check here](/api-reference) to see full API.
56
+
57
+ ### access_token.exp
58
+
59
+ Expires time for `access_token`.
60
+
61
+ ### access_token.secret_key
62
+
63
+ Secret key for JWT when creating `access_token`.
64
+
65
+ ### config.resource_class
66
+
67
+ User model in your application. Usually is `User`.
68
+
69
+ ## Modify User model
70
+
71
+ AuthRails will use method `authenticate` from `has_secure_password` as default.
72
+
73
+ ```rb
74
+ # app/models/user.rb
75
+ class User < ApplicationRecord
76
+ has_secure_password
77
+ end
78
+ ```
79
+
80
+ ## Use AuthRails' default controller
81
+
82
+ Define a route for sign in controller.
83
+
84
+ ```rb
85
+ # frozen_string_literal: true
86
+
87
+ Rails.application.routes.draw do
88
+ namespace :api do
89
+ resource :auth, path: 'auth', controller: 'auth', only: %i[create] do
90
+ collection do
91
+ get :refresh
92
+ end
93
+ end
94
+ end
95
+ end
96
+ ```
97
+
98
+ Create a controller that is inherited from default controller.
99
+
100
+ ```rb
101
+ # frozen_string_literal: true
102
+
103
+ module Api
104
+ class AuthController < AuthRails::Api::AuthController
105
+ end
106
+ end
107
+ ```
108
+
109
+ Now you can sign in using `POST: /api/auth` and refresh the token using `GET: /api/auth/refresh`.
110
+
111
+ Access current user as anytime using `CurrentAuth.user`.
@@ -0,0 +1,21 @@
1
+ # Introduction
2
+
3
+ AuthRails provides a simple authentication API for Ruby on Rails application.
4
+
5
+ ## Features
6
+
7
+ ### API Controller to Sign In User
8
+
9
+ AuthRails provides a default controller to do sign in for your user using JWT.
10
+
11
+ This controller will generate `access_token` to verify user for their next access and `refresh_token` to re-generate `access_token` when it is expired.
12
+
13
+ ### Allowed Token Strategy
14
+
15
+ Allowed Token Strategy will store the `refresh_token` to the database. Only those valid tokens can be used to re-generate `access_token`.
16
+
17
+ Whenever the `refresh_token` is used, it will be deleted and new `refresh_token` is stored in the database.
18
+
19
+ ## Alternative
20
+
21
+ - [devise](https://github.com/heartcombo/devise)
@@ -15,7 +15,7 @@ module AuthRails
15
15
  end
16
16
 
17
17
  def identifier_name
18
- @identifier_name ||= Config.identifier_name.to_sym || :email
18
+ @identifier_name ||= Config.identifier_name&.to_sym || :email
19
19
  end
20
20
 
21
21
  def error_class
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AuthRails
4
- VERSION = '1.1.0'
4
+ VERSION = '1.1.2'
5
5
  end
data/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "auth_rails",
3
+ "version": "1.0.0",
4
+ "author": "Alpha",
5
+ "license": "MIT",
6
+ "scripts": {
7
+ "docs:dev": "vitepress dev docs",
8
+ "docs:build": "vitepress build docs",
9
+ "docs:preview": "vitepress preview docs"
10
+ },
11
+ "devDependencies": {
12
+ "@biomejs/biome": "^1.5.3",
13
+ "typescript": "^5.3.3",
14
+ "vitepress": "1.0.0-rc.40"
15
+ }
16
+ }