I am currently building a RESTful API in PHP which will be used to power both a web and mobile application. As such, the API should be considered public. However, I want to authenticate users when they make requests to the API from either mobile or web.
When a user registers for the service, I generate a unique API key and secret which is stored against the user's record in the database. Ideally, I want requests to be made only using the API key using JavaScript or PHP.
I thought about establishing a hand-shake system for authentication, with the process as follows:
- User makes request to the API using their known key.
- The API responds with a token which is stored in a table along with a timestamp (to prevent replay attacks)
- The token is then used to make the actual request by the client, and the API will check the validity of the token. If the hash matches, and the timestamp is valid, the API provides a valid response, otherwise provides information that the token is expired.
I was thinking to use HMAC to generate the token, something like this:
$token = hash_hmac('sha256', $user->apiKey.microtime(), $user->apiSecret);
The $token will then be stored in the DB, and should be unique for every request. In turn the requests can then be made using the following jQuery code:
$.getJSON('/api/user/get/1', { 'key': '123rrwfnufsd7f72' }).done(function(data) {
// data will now contain a token, so we use it to make another AJAX request:
if( data.token )
{
$.getJSON('/api/user/get/1', { 'token': data.token }).done(function(user) {
// do something with user or handle bad token
});
}
});
My question is will this be sufficient to prevent brute-force and replay attacks?