Module: ApiGuard::JwtAuth::Authentication
- Defined in:
- lib/api_guard/jwt_auth/authentication.rb
Overview
Common module for API authentication
Class Method Summary collapse
-
.authenticate_and_set_resource(resource_name) ⇒ Object
Authenticate the JWT token and set resource.
-
.authenticate_token ⇒ Object
Authenticate the resource with the ‘{resource_name}_id’ in the decoded JWT token and also, check for valid issued at time and not blacklisted.
- .current_resource ⇒ Object
-
.decode_token ⇒ Object
Decode the JWT token and don’t verify token expiry for refresh token API request.
-
.define_current_resource_accessors(resource) ⇒ Object
Defines “current_{resource_name}” method and “@current_{resource_name}” instance variable that returns “resource” value.
- .find_resource_from_token(resource_class) ⇒ Object
-
.method_missing(name, *args) ⇒ Object
Handle authentication of the resource dynamically.
- .respond_to_missing?(method_name, include_private = false) ⇒ Boolean
-
.valid_issued_at?(resource) ⇒ Boolean
Returns whether the JWT token is issued after the last password change Returns true if password hasn’t changed by the user.
Class Method Details
.authenticate_and_set_resource(resource_name) ⇒ Object
Authenticate the JWT token and set resource
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 24 def self.authenticate_and_set_resource(resource_name) @resource_name = resource_name @token = request.headers['Authorization']&.split('Bearer ')&.last return render_error(401, message: I18n.t('api_guard.access_token.missing')) unless @token authenticate_token # Render error response only if no resource found and no previous render happened render_error(401, message: I18n.t('api_guard.access_token.invalid')) if !current_resource && !performed? rescue JWT::DecodeError => e if e. == 'Signature has expired' render_error(401, message: I18n.t('api_guard.access_token.expired')) else render_error(401, message: I18n.t('api_guard.access_token.invalid')) end end |
.authenticate_token ⇒ Object
Authenticate the resource with the ‘{resource_name}_id’ in the decoded JWT token and also, check for valid issued at time and not blacklisted
Also, set “current_{resource_name}” method and “@current_{resource_name}” instance variable for accessing the authenticated resource
72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 72 def self.authenticate_token return unless decode_token resource = find_resource_from_token(@resource_name.classify.constantize) if resource && valid_issued_at?(resource) && !blacklisted?(resource) define_current_resource_accessors(resource) else render_error(401, message: I18n.t('api_guard.access_token.invalid')) end end |
.current_resource ⇒ Object
91 92 93 94 95 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 91 def self.current_resource return unless respond_to?("current_#{@resource_name}") public_send("current_#{@resource_name}") end |
.decode_token ⇒ Object
Decode the JWT token and don’t verify token expiry for refresh token API request
44 45 46 47 48 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 44 def self.decode_token # TODO: Set token refresh controller dynamic verify_token = (controller_name != 'tokens' || action_name != 'create') @decoded_token = decode(@token, verify_token) end |
.define_current_resource_accessors(resource) ⇒ Object
Defines “current_{resource_name}” method and “@current_{resource_name}” instance variable that returns “resource” value
60 61 62 63 64 65 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 60 def self.define_current_resource_accessors(resource) define_singleton_method("current_#{@resource_name}") do instance_variable_get("@current_#{@resource_name}") || instance_variable_set("@current_#{@resource_name}", resource) end end |
.find_resource_from_token(resource_class) ⇒ Object
84 85 86 87 88 89 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 84 def self.find_resource_from_token(resource_class) resource_id = @decoded_token[:"#{@resource_name}_id"] return if resource_id.blank? resource_class.find_by(id: resource_id) end |
.method_missing(name, *args) ⇒ Object
Handle authentication of the resource dynamically
8 9 10 11 12 13 14 15 16 17 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 8 def self.method_missing(name, *args) method_name = name.to_s if method_name.start_with?('authenticate_and_set_') resource_name = method_name.split('authenticate_and_set_')[1] authenticate_and_set_resource(resource_name) else super end end |
.respond_to_missing?(method_name, include_private = false) ⇒ Boolean
19 20 21 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 19 def self.respond_to_missing?(method_name, include_private = false) method_name.to_s.start_with?('authenticate_and_set_') || super end |
.valid_issued_at?(resource) ⇒ Boolean
Returns whether the JWT token is issued after the last password change Returns true if password hasn’t changed by the user
52 53 54 55 56 |
# File 'lib/api_guard/jwt_auth/authentication.rb', line 52 def self.valid_issued_at?(resource) return true unless ApiGuard.invalidate_old_tokens_on_password_change !resource.token_issued_at || @decoded_token[:iat] >= resource.token_issued_at.to_i end |