auth_rails 1.0.0
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 +7 -0
- data/README.md +133 -0
- data/Rakefile +8 -0
- data/app/controllers/auth_rails/api/auth_controller.rb +89 -0
- data/app/controllers/auth_rails/api_controller.rb +8 -0
- data/app/controllers/concerns/auth_rails/authentication.rb +29 -0
- data/app/models/concerns/auth_rails/concerns/allowed_token_strategy.rb +13 -0
- data/app/supports/current_auth.rb +5 -0
- data/auth_rails.gemspec +44 -0
- data/lib/auth_rails/class_methods.rb +25 -0
- data/lib/auth_rails/config.rb +14 -0
- data/lib/auth_rails/configuration/jwt.rb +37 -0
- data/lib/auth_rails/services/jwt_service.rb +41 -0
- data/lib/auth_rails/strategies/allowed_token_strategy.rb +38 -0
- data/lib/auth_rails/strategies/base_strategy.rb +26 -0
- data/lib/auth_rails/version.rb +5 -0
- data/lib/auth_rails.rb +21 -0
- metadata +74 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7b6047449dbddff4af60565f7c096eae14f8800b47bd129dceb3ea7f90fb42f7
|
4
|
+
data.tar.gz: 80776e48b7c557c9ab11ec1e9b05ae06e31bc15cca56a4143bfbf46254d2a109
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 03502ea907678c9ca3122701789e82a145f9c3a143d415153bbde798ad7b5a375cc464ba1e1bf4d8a583d42b298501c00fcf00aadbc7b2be221b8b2044a149fe
|
7
|
+
data.tar.gz: f90cfeab74aa249aebbe6a33deec189901e90c74bfdc0092d42b18a468a3e3eee3fe806611b24accf61a4c1ffc9fc0d1034b4a35cc4bb460fa94b5008790366f
|
data/README.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
Simple authentication for rails.
|
2
|
+
|
3
|
+
# Installation
|
4
|
+
|
5
|
+
```sh
|
6
|
+
gem 'auth_rails'
|
7
|
+
```
|
8
|
+
|
9
|
+
# Configuration
|
10
|
+
|
11
|
+
```rb
|
12
|
+
# config/initializers/auth_rails.rb
|
13
|
+
|
14
|
+
AuthRails.configure do |config|
|
15
|
+
config.jwt do |jwt|
|
16
|
+
jwt.strategy = AuthRails::Strategies::AllowedTokenStrategy # default is AuthRails::Strategies::BaseStrategy
|
17
|
+
|
18
|
+
jwt.access_token do |access_token|
|
19
|
+
access_token.exp = 1.hour.since # optional
|
20
|
+
access_token.algorithm = 'HS256' # optional, default is HS256
|
21
|
+
access_token.secret_key = ENV.fetch('JWT_SECRET', 'secret_key') # optional
|
22
|
+
end
|
23
|
+
|
24
|
+
jwt.refresh_token do |refresh_token|
|
25
|
+
refresh_token.http_only = true # optional
|
26
|
+
refresh_token.exp = 1.year.since # optional
|
27
|
+
refresh_token.algorithm = 'HS256' # optional, must provide if project supports refresh token
|
28
|
+
refresh_token.cookie_key = :project_ref_tok # optional
|
29
|
+
refresh_token.secret_key = ENV.fetch('JWT_SECRET', 'secret_key') # optional
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Rails.application.config.to_prepare do
|
35
|
+
AuthRails.configure do |config|
|
36
|
+
config.resource_class = User # required
|
37
|
+
config.error_class = ProjectError # optional
|
38
|
+
end
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
# Usage
|
43
|
+
|
44
|
+
```rb
|
45
|
+
# config/routes.rb
|
46
|
+
|
47
|
+
Rails.application.routes.draw do
|
48
|
+
namespace :api do
|
49
|
+
resource :auth, path: 'auth', controller: 'auth', only: %i[create] do
|
50
|
+
collection do
|
51
|
+
get :refresh
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
```rb
|
59
|
+
# app/controllers/application_controller.rb
|
60
|
+
|
61
|
+
class ApplicationController < ActionController::API
|
62
|
+
# to include helpers for authenticating using access_token
|
63
|
+
include AuthRails::Authentication
|
64
|
+
|
65
|
+
# this action will assign user to CurrentAuth.user if valid token
|
66
|
+
# else raise error: AuthRails::Error or custom error in configuration
|
67
|
+
before_action :authenticate_user!
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
```rb
|
72
|
+
# app/controllers/api/auth_controller.rb
|
73
|
+
|
74
|
+
module Api
|
75
|
+
class AuthController < AuthRails::Api::AuthController
|
76
|
+
end
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
- If you want to support refresh token
|
81
|
+
|
82
|
+
```rb
|
83
|
+
# app/models/user.rb
|
84
|
+
|
85
|
+
class User < ApplicationRecord
|
86
|
+
include AuthRails::Concerns::AllowedTokenStrategy
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
# Customize
|
91
|
+
|
92
|
+
- Custom Strategy
|
93
|
+
|
94
|
+
```rb
|
95
|
+
class CustomStrategy < AuthRails::Strategies::BaseStrategy
|
96
|
+
class << self
|
97
|
+
# this is for getting user/resource using payload from access_token
|
98
|
+
def retrieve_resource(payload:)
|
99
|
+
super
|
100
|
+
end
|
101
|
+
|
102
|
+
# this is for generating refresh token
|
103
|
+
# if you do not support refresh token, can ignore this one
|
104
|
+
def gen_token(resource:, payload:, exp: nil, secret_key: nil, algorithm: nil)
|
105
|
+
super
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
- Custom response for controller
|
112
|
+
|
113
|
+
```rb
|
114
|
+
module Api
|
115
|
+
class AuthController < AuthRails::Api::AuthController
|
116
|
+
private
|
117
|
+
|
118
|
+
def respond_to_create(data)
|
119
|
+
render json: {
|
120
|
+
profile: CurrentAuth.user,
|
121
|
+
tokens: {
|
122
|
+
auth_token: data[:access_token],
|
123
|
+
refresh_token: data[:refresh_token]
|
124
|
+
}
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
# License
|
132
|
+
|
133
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuthRails
|
4
|
+
module Api
|
5
|
+
class AuthController < ApiController
|
6
|
+
def create
|
7
|
+
resource = AuthRails.resource_class.find_by(email: params[:email])
|
8
|
+
|
9
|
+
raise AuthRails.error_class, :unauthenticated if resource.blank? || !resource.authenticate(params[:password])
|
10
|
+
|
11
|
+
respond_to_create(generate_token(resource))
|
12
|
+
end
|
13
|
+
|
14
|
+
def refresh
|
15
|
+
decoded_payload = Services::JwtService.verify_token(
|
16
|
+
token: lookup_refresh_token,
|
17
|
+
algorithm: Configuration::Jwt::RefreshToken.algorithm,
|
18
|
+
secret_key: Configuration::Jwt::RefreshToken.secret_key
|
19
|
+
)
|
20
|
+
|
21
|
+
resource = AuthRails.jwt_strategy.retrieve_resource(payload: decoded_payload)
|
22
|
+
|
23
|
+
raise AuthRails.error_class, :unauthenticated if resource.blank?
|
24
|
+
|
25
|
+
respond_to_refresh(generate_token(resource))
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def respond_to_create(data)
|
31
|
+
render json: {
|
32
|
+
**data,
|
33
|
+
user: CurrentAuth.user
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
alias respond_to_refresh respond_to_create
|
38
|
+
|
39
|
+
def payload(resource)
|
40
|
+
{
|
41
|
+
sub: resource.email
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def basic_payload
|
46
|
+
{
|
47
|
+
aud: request.host
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def generate_token(resource)
|
52
|
+
CurrentAuth.user = resource
|
53
|
+
token_payload = basic_payload.merge(payload(resource))
|
54
|
+
|
55
|
+
result = {
|
56
|
+
access_token: Services::JwtService.gen_token(
|
57
|
+
payload: token_payload,
|
58
|
+
secret_key: Configuration::Jwt::AccessToken.secret_key
|
59
|
+
)
|
60
|
+
}
|
61
|
+
|
62
|
+
if Configuration::Jwt::RefreshToken.algorithm.present?
|
63
|
+
result[:refresh_token] = AuthRails.jwt_strategy.gen_token(
|
64
|
+
resource: resource,
|
65
|
+
payload: token_payload,
|
66
|
+
exp: Configuration::Jwt::RefreshToken.exp.to_i,
|
67
|
+
algorithm: Configuration::Jwt::RefreshToken.algorithm,
|
68
|
+
secret_key: Configuration::Jwt::RefreshToken.secret_key
|
69
|
+
)
|
70
|
+
|
71
|
+
cookie_http_only(result[:refresh_token])
|
72
|
+
end
|
73
|
+
|
74
|
+
result
|
75
|
+
end
|
76
|
+
|
77
|
+
def cookie_http_only(refresh_token)
|
78
|
+
return if Configuration::Jwt::RefreshToken.http_only.blank?
|
79
|
+
|
80
|
+
cookies[Configuration::Jwt::RefreshToken.cookie_key.to_sym || :ref_tok] = {
|
81
|
+
httponly: true,
|
82
|
+
value: refresh_token,
|
83
|
+
secure: Rails.env.production?,
|
84
|
+
expires: Time.at(Configuration::Jwt::RefreshToken.exp).to_datetime
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuthRails
|
4
|
+
module Authentication
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def authenticate_user!
|
8
|
+
payload = Services::JwtService.verify_token(
|
9
|
+
token: lookup_access_token,
|
10
|
+
secret_key: Configuration::Jwt::AccessToken.secret_key
|
11
|
+
)
|
12
|
+
|
13
|
+
CurrentAuth.user = AuthRails.resource_class.find_by(email: payload[:sub])
|
14
|
+
|
15
|
+
raise AuthRails.error_class, :unauthenticated unless CurrentAuth.user
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def lookup_access_token
|
21
|
+
token_match = request.headers['Authorization']&.match(/bearer (.+)/i)
|
22
|
+
token_match[1] if token_match
|
23
|
+
end
|
24
|
+
|
25
|
+
def lookup_refresh_token
|
26
|
+
cookies[Configuration::Jwt::RefreshToken.cookie_key.to_sym].presence || params[:refresh_token]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/auth_rails.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/auth_rails/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'auth_rails'
|
7
|
+
spec.version = AuthRails::VERSION
|
8
|
+
spec.authors = ['Alpha']
|
9
|
+
spec.email = ['alphanolucifer@gmail.com']
|
10
|
+
|
11
|
+
spec.summary = 'Simple authentication for Rails'
|
12
|
+
spec.description = 'Simple authentication for Rails'
|
13
|
+
spec.homepage = 'https://github.com/zgid123/auth_rails'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.required_ruby_version = '>= 2.6.0'
|
16
|
+
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
+
|
19
|
+
spec.files = Dir.chdir(__dir__) do
|
20
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
21
|
+
(File.expand_path(f) == __FILE__) ||
|
22
|
+
f.start_with?(
|
23
|
+
*%w[
|
24
|
+
bin/
|
25
|
+
test/
|
26
|
+
spec/
|
27
|
+
features/
|
28
|
+
.git
|
29
|
+
.circleci
|
30
|
+
appveyor
|
31
|
+
Gemfile
|
32
|
+
.rubocop.yml
|
33
|
+
.vscode/settings.json
|
34
|
+
LICENSE.txt
|
35
|
+
lefthook.yml
|
36
|
+
]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
spec.require_paths = ['lib']
|
42
|
+
|
43
|
+
spec.add_dependency 'jwt'
|
44
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuthRails
|
4
|
+
class << self
|
5
|
+
def configure
|
6
|
+
yield Config
|
7
|
+
end
|
8
|
+
|
9
|
+
def configuration
|
10
|
+
Config
|
11
|
+
end
|
12
|
+
|
13
|
+
def resource_class
|
14
|
+
@resource_class ||= Config.resource_class
|
15
|
+
end
|
16
|
+
|
17
|
+
def error_class
|
18
|
+
@error_class ||= Config.error_class || Error
|
19
|
+
end
|
20
|
+
|
21
|
+
def jwt_strategy
|
22
|
+
@jwt_strategy ||= Configuration::Jwt.strategy || Strategies::BaseStrategy
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuthRails
|
4
|
+
module Configuration
|
5
|
+
class Jwt
|
6
|
+
class << self
|
7
|
+
attr_accessor :strategy
|
8
|
+
|
9
|
+
def access_token
|
10
|
+
yield AccessToken
|
11
|
+
|
12
|
+
AccessToken.algorithm ||= 'HS256'
|
13
|
+
end
|
14
|
+
|
15
|
+
def refresh_token
|
16
|
+
yield RefreshToken
|
17
|
+
|
18
|
+
RefreshToken.cookie_key ||= :ref_tok
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class AccessToken
|
23
|
+
class << self
|
24
|
+
attr_accessor :exp,
|
25
|
+
:algorithm,
|
26
|
+
:secret_key
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class RefreshToken < AccessToken
|
31
|
+
class << self
|
32
|
+
attr_accessor :http_only, :cookie_key
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuthRails
|
4
|
+
module Services
|
5
|
+
class JwtService
|
6
|
+
class << self
|
7
|
+
def gen_token(payload:, exp: nil, secret_key: nil, algorithm: nil, jti: nil)
|
8
|
+
exp ||= Configuration::Jwt::AccessToken.exp.to_i
|
9
|
+
|
10
|
+
JWT.encode(
|
11
|
+
(payload || {}).merge(jti: jti || SecureRandom.hex(20)),
|
12
|
+
secret_key,
|
13
|
+
algo(algorithm),
|
14
|
+
{
|
15
|
+
exp: exp.to_i
|
16
|
+
}
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def verify_token(token:, secret_key: nil, algorithm: nil)
|
21
|
+
JWT.decode(
|
22
|
+
token,
|
23
|
+
secret_key,
|
24
|
+
true,
|
25
|
+
{
|
26
|
+
algorithm: algo(algorithm)
|
27
|
+
}
|
28
|
+
)[0].deep_symbolize_keys
|
29
|
+
rescue StandardError
|
30
|
+
{}
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def algo(algorithm)
|
36
|
+
algorithm || Configuration::Jwt::AccessToken.algorithm
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuthRails
|
4
|
+
module Strategies
|
5
|
+
class AllowedTokenStrategy < BaseStrategy
|
6
|
+
class << self
|
7
|
+
def retrieve_resource(payload:)
|
8
|
+
symbolized_payload = payload.symbolize_keys
|
9
|
+
|
10
|
+
AuthRails.resource_class
|
11
|
+
.joins(:allowed_tokens)
|
12
|
+
.where(allowed_tokens: symbolized_payload.slice(:jti, :aud))
|
13
|
+
.where('allowed_tokens.exp > ?', Time.current)
|
14
|
+
.find_by(email: symbolized_payload[:sub])
|
15
|
+
end
|
16
|
+
|
17
|
+
def gen_token(resource:, payload:, exp: nil, secret_key: nil, algorithm: nil)
|
18
|
+
jti = SecureRandom.hex(20)
|
19
|
+
|
20
|
+
resource.allowed_tokens
|
21
|
+
.create!(
|
22
|
+
jti: jti,
|
23
|
+
aud: payload[:aud],
|
24
|
+
exp: Time.zone.at(exp)
|
25
|
+
)
|
26
|
+
|
27
|
+
super(
|
28
|
+
jti: jti,
|
29
|
+
exp: exp,
|
30
|
+
payload: payload,
|
31
|
+
algorithm: algorithm,
|
32
|
+
secret_key: secret_key
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AuthRails
|
4
|
+
module Strategies
|
5
|
+
class BaseStrategy
|
6
|
+
class << self
|
7
|
+
def retrieve_resource(payload:)
|
8
|
+
symbolized_payload = payload.symbolize_keys
|
9
|
+
|
10
|
+
AuthRails.resource_class
|
11
|
+
.find_by(email: symbolized_payload[:sub])
|
12
|
+
end
|
13
|
+
|
14
|
+
def gen_token(payload:, exp: nil, secret_key: nil, algorithm: nil, jti: nil, **)
|
15
|
+
Services::JwtService.gen_token(
|
16
|
+
exp: exp,
|
17
|
+
jti: jti,
|
18
|
+
payload: payload,
|
19
|
+
algorithm: algorithm,
|
20
|
+
secret_key: secret_key
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/auth_rails.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'auth_rails/config'
|
4
|
+
require_relative 'auth_rails/version'
|
5
|
+
require_relative 'auth_rails/class_methods'
|
6
|
+
require_relative 'auth_rails/configuration/jwt'
|
7
|
+
require_relative 'auth_rails/services/jwt_service'
|
8
|
+
require_relative 'auth_rails/strategies/base_strategy'
|
9
|
+
require_relative 'auth_rails/strategies/allowed_token_strategy'
|
10
|
+
|
11
|
+
module AuthRails
|
12
|
+
class Error < StandardError; end
|
13
|
+
|
14
|
+
class Engine < ::Rails::Engine
|
15
|
+
isolate_namespace AuthRails
|
16
|
+
|
17
|
+
config.autoload_paths << File.expand_path('app/models', __dir__)
|
18
|
+
config.autoload_paths << File.expand_path('app/supports', __dir__)
|
19
|
+
config.autoload_paths << File.expand_path('app/controllers', __dir__)
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: auth_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alpha
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-12-25 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: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Simple authentication for Rails
|
28
|
+
email:
|
29
|
+
- alphanolucifer@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- Rakefile
|
36
|
+
- app/controllers/auth_rails/api/auth_controller.rb
|
37
|
+
- app/controllers/auth_rails/api_controller.rb
|
38
|
+
- app/controllers/concerns/auth_rails/authentication.rb
|
39
|
+
- app/models/concerns/auth_rails/concerns/allowed_token_strategy.rb
|
40
|
+
- app/supports/current_auth.rb
|
41
|
+
- auth_rails.gemspec
|
42
|
+
- lib/auth_rails.rb
|
43
|
+
- lib/auth_rails/class_methods.rb
|
44
|
+
- lib/auth_rails/config.rb
|
45
|
+
- lib/auth_rails/configuration/jwt.rb
|
46
|
+
- lib/auth_rails/services/jwt_service.rb
|
47
|
+
- lib/auth_rails/strategies/allowed_token_strategy.rb
|
48
|
+
- lib/auth_rails/strategies/base_strategy.rb
|
49
|
+
- lib/auth_rails/version.rb
|
50
|
+
homepage: https://github.com/zgid123/auth_rails
|
51
|
+
licenses:
|
52
|
+
- MIT
|
53
|
+
metadata:
|
54
|
+
homepage_uri: https://github.com/zgid123/auth_rails
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 2.6.0
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
requirements: []
|
70
|
+
rubygems_version: 3.4.13
|
71
|
+
signing_key:
|
72
|
+
specification_version: 4
|
73
|
+
summary: Simple authentication for Rails
|
74
|
+
test_files: []
|