3 ms·
I have semi-copied what AWS did a couple of years ago. Each api consumer has an api key with a private key known to the consumer and server-side. Requests are
by tom_b 10y ago
I have semi-copied what AWS did a couple of years ago. Each api consumer has an api key with a private key known to the consumer and server-side. Requests are SSL only and are signed with the private key by the consumer side (including any parameters and a client-side timestamp). For example, using curl:
#!/bin/bash
TS=$(date +"%s000")
SIG=$(echo -ne 'GET\nhttps://servername:port/api/resources?api_id=1&ts='$TS | openssl dgst -sha256 -hmac "secret-key" -binary | xxd -p -c 32)
curl -H "Content-type: application/vnd.collection+json" 'https://servername:port/api/resources?api_id=1&ts='$TS'&signature='$SIG
I have consumers of the api using node.js and Java as app dev languages with various http client libraries successfully. The actual server-side api is written with Clojure using the Liberator library (highly enjoyed working with this combo).
Server-side uses the api_id to check the signature using the shared secretkey. (Edit to clarify). There are two timestamps flying around here. One is a timestamp from the client call to the api ($TS above). This timestamp has to be "close" - completely configurable on server-side - to the server-side time or the request is not valid. A little more subtle is that each resource has a timestamp that is the last time the resource was changed server-side. As part of the authorization for the api call to change a resource, it has to be make the call to the api with the resource's most current value for that timestamp to succeed. This is a little goofy logically.
This approach works very well when you have a requirement to allow multiple different apps to call the api rather than say, allowing users to call the api from their browser. I don't have a case where users are in a web browser app that directly calls the REST api.
By the way, if you are using SSL, you don't have to worry about the api_id being exposed in either the query parameters or the request headers.