Class: Grape::Jwt::Authentication::JwtHandler
- Inherits:
-
Object
- Object
- Grape::Jwt::Authentication::JwtHandler
- Defined in:
- lib/grape/jwt/authentication/jwt_handler.rb
Overview
Take care of the token validation and verification on this Rack middleware. It is a self contained implementation of a valid Rack handler which checks for a common JWT token Authorization header and calls a user given verification block which performs the database lookup or whatever is necessary for the verification.
Defined Under Namespace
Classes: AuthenticationError, MalformedHeaderError
Constant Summary collapse
- JWT_PART_REGEX =
A generic JWT part, the full token contains three parts separated by a period.
/([a-zA-Z0-9\-_]+)?/.freeze
- JWT_REGEX =
A common JWT validation regex which meets the RFC specs.
Regexp.new("^#{([JWT_PART_REGEX] * 3).join('\.')}$").freeze
Instance Method Summary collapse
-
#authenticator ⇒ Proc
Get the local or global defined authenticator for the JWT handler.
-
#call(env) ⇒ Object
Perform the authentication logic on the Rack compatible interface.
-
#config(key, global_key) ⇒ Mixed
A shared configuration lookup helper which selects the requested entry from the local or global configuration object.
-
#failed_handler ⇒ Proc
Get the local or global defined failed authentication handler for the JWT handler.
-
#initialize(app, options = {}) ⇒ JwtHandler
constructor
Initialize a new Rack middleware for Bearer token processing.
-
#inject_token_into_env(env, token) ⇒ Object
Inject the token to the environment as a parsed version.
-
#malformed_handler ⇒ Proc
Get the local or global defined malformed authentication handler for the JWT handler.
-
#parse_token(header) ⇒ String
Validate the Bearer authentication scheme on the given authorization header and validate the JWT token when it was found.
Constructor Details
#initialize(app, options = {}) ⇒ JwtHandler
Initialize a new Rack middleware for Bearer token processing.
30 31 32 33 |
# File 'lib/grape/jwt/authentication/jwt_handler.rb', line 30 def initialize(app, = {}) @app = app @options = end |
Instance Method Details
#authenticator ⇒ Proc
Get the local or global defined authenticator for the JWT handler.
54 55 56 |
# File 'lib/grape/jwt/authentication/jwt_handler.rb', line 54 def authenticator config(:proc, :authenticator) end |
#call(env) ⇒ Object
Perform the authentication logic on the Rack compatible interface.
because thats the auth handling core :reek:TooManyStatements because reek counts exception
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/grape/jwt/authentication/jwt_handler.rb', line 107 def call(env) # Unfortunately Grape's middleware stack orders the error # handling higher than the formatter. So when a error is # raised, the Rack env was not yet analysed and the content # type not negotiated. This would result in allways-JSON # responses on authentication errors. We want to be smarter # here and respond in the requested format on authentication # errors, that why we invoke the formatter middleware here. Grape::Middleware::Formatter.new(->(_) {}).call(env) # Parse the JWT token from the request headers. # Downcase the header keys to account for HTTP/2+ # semantics in Grape 2.0.0+ lowercase_env = env.transform_keys(&:downcase) token = parse_token(lowercase_env['http_authorization']) # Inject the parsed token to the Rack environment. inject_token_into_env(env, token) # Give the parsed token to the user defined block # for futher verification. The user given block MUST return # a positive result to allow the request to be further # processed, or a negative result to stop processing. raise AuthenticationError unless authenticator.call(token) # Looks like we are on a good path and the given token was # valid on all checks. So we continue the regular # application logic now. @app.call(env) rescue MalformedHeaderError # Call the user defined malformed authentication handler. malformed_handler.call(env['HTTP_AUTHORIZATION'], @app) rescue AuthenticationError # Call the user defined failed authentication handler. failed_handler.call(token, @app) end |
#config(key, global_key) ⇒ Mixed
A shared configuration lookup helper which selects the requested entry from the local or global configuration object. The local configuration takes presedence over the global one.
42 43 44 45 46 47 48 49 |
# File 'lib/grape/jwt/authentication/jwt_handler.rb', line 42 def config(key, global_key) block = @options[key] unless block global_conf = Grape::Jwt::Authentication.configuration return global_conf.send(global_key) end block end |
#failed_handler ⇒ Proc
Get the local or global defined failed authentication handler for the JWT handler.
70 71 72 |
# File 'lib/grape/jwt/authentication/jwt_handler.rb', line 70 def failed_handler config(:failed, :failed_auth_handler) end |
#inject_token_into_env(env, token) ⇒ Object
Inject the token to the environment as a parsed version. This allows further usage like extracting the subject from the payload when the verification was valid.
93 94 95 96 97 98 99 |
# File 'lib/grape/jwt/authentication/jwt_handler.rb', line 93 def inject_token_into_env(env, token) env['grape_jwt_auth.parsed_token'] = Keyless::Jwt.new(token) rescue *Keyless::Jwt::RESCUE_JWT_EXCEPTIONS env['grape_jwt_auth.parsed_token'] = nil ensure env['grape_jwt_auth.original_token'] = token end |
#malformed_handler ⇒ Proc
Get the local or global defined malformed authentication handler for the JWT handler.
62 63 64 |
# File 'lib/grape/jwt/authentication/jwt_handler.rb', line 62 def malformed_handler config(:malformed, :malformed_auth_handler) end |
#parse_token(header) ⇒ String
Validate the Bearer authentication scheme on the given authorization header and validate the JWT token when it was found.
80 81 82 83 84 85 |
# File 'lib/grape/jwt/authentication/jwt_handler.rb', line 80 def parse_token(header) token = header.to_s.scan(/^Bearer (.*)/).flatten.first raise MalformedHeaderError unless JWT_REGEX =~ token token end |