Rails Plugin for API Key + Secret Key Signing

Rails plugin for API Key + Secret Key signing

Check out this plugin for AuthLogic:

http://github.com/phurni/authlogic_api

I think that does what you are looking for.

Looking for suggestions for building a secure REST API within Ruby on Rails

There are several schemes for authenticating API requests, and they're different than normal authentication provided by plugins like restful_authentication or acts_as_authenticated. Most importantly, clients will not be maintaining sessions, so there's no concept of a login.

HTTP Authentication

You can use basic HTTP authentication. For this, API clients will use a regular username and password and just put it in the URL like so:

http://myusername:mypass@www.someapp.com/

I believe that restful_authentication supports this out of the box, so you can ignore whether or not someone is using your app via the API or via a browser.

One downside here is that you're asking users to put their username and password in the clear in every request. By doing it over SSL, you can make this safe.

I don't think I've ever actually seen an API that uses this, though. It seems like a decently good idea to me, especially since it's supported out of the box by the current authentication schemes, so I don't know what the problem is.

API Key

Another easy way to enable API authentication is to use API keys. It's essentially a username for a remote service. When someone signs up to use your API, you give them an API key. This needs to be passed with each request.

One downside here is that if anyone gets someone else's API key, they can make requests as that user. I think that by making all your API requests use HTTPS (SSL), you can offset this risk somewhat.

Another downside is that users use the same authentication credentials (the API key) everywhere they go. If they want to revoke access to an API client their only option is to change their API key, which will disable all other clients as well. This can be mitigated by allowing users to generate multiple API keys.

API Key + Secret Key signing

Deprecated(sort of) - see OAuth below

Significantly more complex is signing the request with a secret key. This is what Amazon Web Services (S3, EC2, and such do). Essentially, you give the user 2 keys: their API key (ie. username) and their secret key (ie. password). The API key is transmitted with each request, but the secret key is not. Instead, it is used to sign each request, usually by adding another parameter.

IIRC, Amazon accomplishes this by taking all the parameters to the request, and ordering them by parameter name. Then, this string is hashed, using the user's secret key as the hash key. This new value is appended as a new parameter to the request prior to being sent. On Amazon's side, they do the same thing. They take all parameters (except the signature), order them, and hash using the secret key. If this matches the signature, they know the request is legitimate.

The downside here is complexity. Getting this scheme to work correctly is a pain, both for the API developer and the clients. Expect lots of support calls and angry emails from client developers who can't get things to work.

OAuth

To combat some of the complexity issues with key + secret signing, a standard has emerged called OAuth. At the core OAuth is a flavor of key + secret signing, but much of it is standardized and has been included into libraries for many languages.

In general, it's much easier on both the API producer and consumer to use OAuth rather than creating your own key/signature system.

OAuth also inherently segments access, providing different access credentials for each API consumer. This allows users to selectively revoke access without affecting their other consuming applications.

Specifically for Ruby, there is an OAuth gem that provides support out of the box for both producers and consumers of OAuth. I have used this gem to build an API and also to consume OAuth APIs and was very impressed. If you think your application needs OAuth (as opposed to the simpler API key scheme), then I can easily recommend using the OAuth gem.

Where should I store api key in rails3?

I use the settingslogic plugin for things like this. Very easy to use.

Add settingslogic to your Gemfile and bundle install:

gem 'settingslogic'

Create a directory for your settings and place the settingslogic yaml in there:

/my_app/config/settings/my_settings.yml

You can include default settings and per environment settings. The file looks like this:

defaults: &defaults
api_key: abc123

development:
<<: *defaults

test:
<<: *defaults

production:
<<: *defaults

Add this file: app/models/my_settings.rb, start up your app and you are good to go

class MySettings < Settingslogic
source "#{Rails.root}/config/settings/my_settings.yml"
namespace Rails.env
end

Now you can use call these settings from anywhere in the app like so:

MySettings.api_key

hiding keys in production rails 4

So, I thought about using the Figaro gem but I ended up using rbenv-vars by sstephenson:
https://github.com/sstephenson/rbenv-vars

On the Amazon Server, I made a directory:
$ mkdir -p ~/.rbenv/plugins
$ cd ~/.rbenv/plugins
$ git clone https://github.com/sstephenson/rbenv-vars.git
$ rbenv rehash

Then, on the AWS server, I used vim to create a file:
$ vim .rbenv-vars
$ rake secret in your project directory to get a SECRET_KEY_BASE=place key here

Then I added this .rbenv-vars to the .gitignore.
Of course you don't want to send these keys to Github.

In this file, you can also place your secret keys where they'll reside on the server to do their job.

Does Geokit use a default google API key?

I'm the maintainer of geokit. Yes, you can use it without a key, though I personally feel it would be unwise to do so in production.

But it is nice for "trying" the gem, though you'll hit your limit very quickly (you might even get that error straight away depending on how google limit, e.g. by IP)

See the README to easily set this:

# See https://developers.google.com/maps/documentation/geocoding/#api_key
Geokit::Geocoders::GoogleGeocoder.api_key = ''

api authentication in rails 3

In this situation, HTTP Basic authentication would work fine. If you'd like it to be more secure, you could create an OAuth provider and create your own implementation of Twitter xAuth to make it more user friendly. Essentially, you'd create an API call that would accept a username and password and then return an OAuth request token for that user. You'd store that request token on the iPhone and use it to authenticate subsequent requests.



Related Topics



Leave a reply



Submit