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 :-
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.
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?
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.
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.
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.
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.
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…
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?
hmac_sha2 is jiberish that is virtually impossible to decrypt so there is no plain text password in the request.
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:
you have a timestamp
you have a unique transactionID (UUID is excelent for this)
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.