General Questions - API related

Hi all,

This is more of a general discussion rather than related to Railo or ColdBox… I am working on an API (in ColdFusion) and although the API is going to be massive, I am only currently doing a few of the API calls. My questions are below :-

  1. What is the best way to ask for an API key from the callers? In the Request Headers or as a required parameter in the API calls or both? I have seen quite a few API’s doing either or both. So, not sure what is the best way to do this.

  2. If a particular API call only supports GET method, then should I be checking for the HTTP method in the headers and rejecting any other methods but GET? Or is it OK to let any methods come in?

  3. In general, what are the best practices to authenticate an API call? A lot of API’s nowadays do this via oAuth and I am not sure I am willing to go through the complexity of implementing that if there is an easier way. I found this article http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/ but your thoughts would be much appreciated.

Thanks a lot in advance for taking the time to reply to this.

Regards,
Anuj Gakhar

  1. What is the best way to ask for an API key from the callers? In the Request Headers or as a required parameter in the API calls or both? I have seen quite a few API’s doing either or both. So, not sure what is the best way to do this.

I kind of prefer the headers for api keys and the such and leave parameters for actual parameters to the resources. Or you can do an approach where it could be in the header OR parameter.

  1. If a particular API call only supports GET method, then should I be checking for the HTTP method in the headers and rejecting any other methods but GET? Or is it OK to let any methods come in?

I would agree on locking down the verbs and definitely documenting it. As you might use the verb for something else later. So lock as much as you can either using the this.allowedMethods locally which you can catch the exceptions with onError() very easily. Or do it at the router level via RESTful actions.

  1. In general, what are the best practices to authenticate an API call? A lot of API’s nowadays do this via oAuth and I am not sure I am willing to go through the complexity of implementing that if there is an easier way. I found this article http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/ but your thoughts would be much appreciated.

My two cents would be use use a combination of strategies. SSL is a must for security to avoid sniffing and clear text being passed around. Then you can use a registered API key that’s sent on every request in the headers. And if you want to be extra picky, then provide some HMAC encryption of your payload and provide an apikey and secret key to your clients. You can also do time expired requests.

Luis F. Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Social: twitter.com/lmajano facebook.com/lmajano

Hi Luis,

Thanks a lot for your input. Discussing this topic here makes me feel confident about what I am doing :slight_smile:

Cheers

Hi Anuj,

I always preferred adding an HMAC SHA2 checksum as a parameter, as this ensures that even if the request gets captured somewhere, they won’t be able to change minor parameter values and repost, as that would change the checksum of the request. So the best they could do is just resend the same request over and over and that is easy to trap on your side…

Cheers,
Tom Van Schoor

That makes sense, Tom. That was the next thing on my list - detecting the rate at which the API is being called. Is it simply a matter of checking the IP and making sure a certain IP does not send too many requests too frequently or is it more involved than that?

The thing about adding a HMAC SHA2 checksum into your request parameters…

First thing to know is that it is secure… banks use it to protect transactions.

Normally you would have credentials in a request, for instance:

Username = someUser
Password = somePassword
requestDate = someDatestamp
transactionID = someUniqueValue (UUID?)
transactionAmount = $10000.00

Something like that, obviously you now have a password sent in plain text and I would advise against that…

So to get rid of the password in the request you could ask user to post:

Username = someUser
requestDate = someDatestamp
transactionID = someUniqueValue
transactionAmount = $10000.00
checksum = hmac_sha2(“password”,“someUsersomeDatestampsomeUniqueValue$10000.00”)

  1. hmac_sha2 is jiberish that is virtually impossible to decrypt so there is no plain text password in the request.
  2. if a character in the parameters changes, the checksum would have to change and hackers will not be able to generate the checksum without knowing the password.

On your side you recalculate the checksum with the password you have in the database for this username and if the checksum is the same, the request is legitimate.

If someone resends the same request, you have a number of options to declare it as a duplicate transaction:

  1. you have a timestamp
  2. you have a unique transactionID (UUID is excelent for this)

Does that make sense?

Cheers,
Tom Van Schoor

Sure, thanks for the great explanation and example… makes it much more clear in my head

You r welcome…

I just read the article you mentioned and now notice that it explains the same thing in a whole lot more words :smiley:

I did not get it from Amazon though, I got it from having to write systems for online payments for acquirers and credit card providers :wink:

Cheers,
Tom

Tom do you have a sample to post on this? Maybe a cool hmac plugin to add to forgebox?

Well Luis we will eventually need it for our new and improved coldbox based API, so I will see what I can do… Maybe a nice first forgebox contribution. :slight_smile:

That’s great Tom - could be just in time for me then :slight_smile:

Yes, that would be great Tom!

Luis F. Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Social: twitter.com/lmajano facebook.com/lmajano

I wrote up whatever I’ve learned/read last few weeks on how to design a good RESTful API in a blog post

http://www.anujgakhar.com/2011/11/16/designing-a-restful-api/

Your thoughts/feedback would be very helpful.