ApiAuthenticator
This gem will authenticate API requests using a slightly modified version HMAC-SHA1
Installation
Add this line to your application's Gemfile:
gem 'api_authenticator'
And then execute:
$ bundle
Or install it yourself as:
$ gem install api_authenticator
Authentication
This gem assumes headers being pass into the request. The two headers are:
- API-Time
- API-Token
API-Time
The API-Time is a String UTC representation of the current time of request.
For example:
=> "2014-10-16 18:55:48 UTC"
API-Token
The token passed in is a SHA256 of the time AND the request URL. The shared_secret_key is used as the encyrption key.
digest = OpenSSL::Digest.new('sha256')
env['API-Token'] = OpenSSL::HMAC.hexdigest(digest, shared_secret_key, "#{DateTime.now.new_offset(0)}#{request.original_url}")
Configuration
ApiAuthenticator.configure do |config|
config.shared_secret_keys = ["my_shared_token", "my_shared_token2"]
config.time_threshold = 2.hours
config.request_type = :path # :url by default if nothing is set
config.logger = Rails.logger
config.report_unauthenticated_requests = true
end
- shared_secret_keys: An Array of approved shared secret keys between the client and the server.
- time_threshold: The time threshold to allow requests. So for example the entry above will only allow requests from 2 hours before now and 2 hours in the future.
- request_type: 2 options: :url or :path. By default it's :url which uses the full URL has as the hashing mechanism. :path only uses the path for the hashing mechanism.
- logger: Your logger
- report_unauthenticated_requests: will throw some basic information into your logger.warn.
Usage
There is a before_filter that is included in the gem. If not authenticated it will automatically render a status 401.
class ApiController
include ApiAuthenticator
before_filter :api_authenticator
end
Or you can use it without the before_filter. Note here is that right now, if the request is not authenticated the gem with throw an exception. All exceptions inherit from ApiAuthentiactor::BaseError
class ApiController
def people
# Takes a Rails request object
begin
ApiAuthentiactor.authenticated_request?(request)
rescue ApiAuthenticator::InvalidTimeError => e
logger.error(e)
rescue ApiAuthenticator::InvalidTokenError => e
logger.error(e)
end
end
end
TODO:
- Set time intervals instead of explicity passing in the time.
Running The Specs
Just run rake:
rake
Upggrading from 0.1.0 to 0.2.0
The big change here is ApiAuthenticator now takes a list of shared secret keys. So where there was
ApiAuthenticator.shared_secret_key = 'key1'
it now takes an array
ApiAuthenticator.shared_secret_keys = ['key1', 'key2']
Contributing
- Fork it ( https://github.com/[my-github-username]/api_authenticator/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request