Class: RackApiKey
- Inherits:
-
Object
- Object
- RackApiKey
- Defined in:
- lib/rack-api-key.rb,
lib/rack-api-key/version.rb
Overview
RackApiKey is a middleware that relies on the client submitting requests with a header named “X-API-KEY” storing their private API key as the value. The middleware will then intercept the request, read the value from the named header and call the given “proc” used for API key lookup. The API key lookup should only return a value if there is an exact match for the value stored in the named API key header.
If such a API key exists, the middleware will pass the request onward and also set a new value in the request representing the authenticated API key. Otherwise the middleware will return a HTTP status of 401, and a plain text message notifying the calling requestor that they are not authorized.
Constant Summary collapse
- VERSION =
"0.0.3"
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, options = {}) ⇒ RackApiKey
constructor
Options *
:api_key_proc
- REQUIRED A proc that is intended to lookup the API key in your datastore. -
#rack_api_key_request_setter(env, api_key_lookup_val) ⇒ Object
Sets the API key lookup value in the request.
-
#unauthorized_api_key ⇒ Object
Returns a 401 HTTP status code when an API key is not found or is not authorized.
-
#valid_api_key?(api_header_val, api_key_lookup_val) ⇒ Boolean
Checks if the API key header value is present and the API key that was returned from the API key proc is present.
Constructor Details
#initialize(app, options = {}) ⇒ RackApiKey
Options
-
:api_key_proc
- REQUIRED A proc that is intended to lookup the API key in your datastore.The given proc should take an argument, namely the value of the API key header. There is no default value for this option and will raise a NotImplementedError if left unspecified.
-
:rack_api_key
- A way to override the key’s name set in the requeston successful authentication. The default value is "rack_api_key".
-
:header_key
- A way to override the header’s name used to store the API key.The value given here should reflect how Rack interprets the header. For example if the client passes "X-API-KEY" Rack transforms interprets it as "HTTP_X_API_KEY". The default value is "HTTP_X_API_KEY".
-
:url_restriction
- A way to restrict specific URLs that should pass throughthe rack-api-key middleware. In order to use pass an Array of Regex patterns. If left unspecified all requests will pass through the rack-api-key middleware.
-
:url_exclusion
- A way to exclude specific URLs that should not pass through thethe rack-api-middleware. In order to use, pass an Array of Regex patterns.
Example
use RackApiKey,
:api_key_proc => Proc.new { |key| ApiKey.where(:key => key).first },
:rack_api_key => "authenticated.api.key",
:header_key => "HTTP_X_SECRET_API_KEY",
:url_restriction => [/api/],
:url_exclusion => [/api\/status/]
50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/rack-api-key.rb', line 50 def initialize(app, = {}) @app = app = { :header_key => 'HTTP_X_API_KEY', :rack_api_key => 'rack_api_key', :api_key_proc => Proc.new { raise NotImplementedError.new('Caller must implement a way to lookup an API key.') }, :url_restriction => [], :url_exclusion => [] } @options = .merge() end |
Instance Method Details
#call(env) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rack-api-key.rb', line 62 def call(env) if constraint?(:url_exclusion) && url_matches(:url_exclusion, env) @app.call(env) elsif constraint?(:url_restriction) url_matches(:url_restriction, env) ? process_request(env) : @app.call(env) else process_request(env) end end |
#rack_api_key_request_setter(env, api_key_lookup_val) ⇒ Object
Sets the API key lookup value in the request. Intentionally left here if anyone wants to change or override what does or does not get set in the request.
84 85 86 |
# File 'lib/rack-api-key.rb', line 84 def rack_api_key_request_setter(env, api_key_lookup_val) env[@options[:rack_api_key]] = api_key_lookup_val end |
#unauthorized_api_key ⇒ Object
Returns a 401 HTTP status code when an API key is not found or is not authorized. Intentionally left here if anyone wants to override this functionality, specifically change the format of the message or the media type.
93 94 95 96 97 |
# File 'lib/rack-api-key.rb', line 93 def body_text = 'The API key provided is not authorized.' [401, {'Content-Type' => 'text/plain; charset=utf-8', 'Content-Length' => body_text.size.to_s}, [body_text]] end |
#valid_api_key?(api_header_val, api_key_lookup_val) ⇒ Boolean
Checks if the API key header value is present and the API key that was returned from the API key proc is present. Intentionally left here is anyone wants to override this functionality.
103 104 105 106 |
# File 'lib/rack-api-key.rb', line 103 def valid_api_key?(api_header_val, api_key_lookup_val) !api_header_val.nil? && api_header_val != '' && !api_key_lookup_val.nil? && api_key_lookup_val != '' end |