I\'ve developed few web APIs in PHP using Slim framework which are used by mobile apps(iOS and Android) to process their requests and get the required data.
Eventual
You could do it this way.
Each user has a private key (a random alpha-numeric x long string) - which is unique to each user.
On every request, you can hash_hmac
the request with their private key which will generate a unique request key for each user. For example:
Request:
GET /v1/products/coffee
Private key:
ww9k6fcysu30sbuzu7ez57z2kzvefyxwosrjcnwo
I would then generate a request key like;
hash_hmac("sha1", "GET /v1/products/coffee", "ww9k6fcysu30sbuzu7ez57z2kzvefyxwosrjcnwo");
This would give me a request key of: 45751dce6ef93655a71e7b82a6179591c346c2c1
for this GET
request only. It will also ensure the client intended for this endpoint and hasn't been tampered with.
On the receiving end you would perform the same hash_hmac
routine with the users private key (they would need to pass in their username in the request - for example - to perform a lookup to fetch the private key) and compare the two results.
hash_hmac("sha1", $_SERVER['REQUEST_METHOD'] . " " . $_SERVER['REDIRECT_URL'], $user_private_key);
For added bonus, you would get a hash for POST/PUT body content and append that in the request query string and authenticate that on the receiving end. For example;
$bodyhash = md5(implode(",", $_POST));
When a user logs out, deactivate the private key and assign them a new one on next login.
Based on our discussion, you could do something akin to OAuth2.0. I would recommend implementing the full spec, but since it is your application, you could make changes.
Here is a graph from RFC 6750
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| (Slim API) |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
In slim, you could have as few as three endpoints:
POST username/password:
/oauth/v1/authenticate/
returns { token: foo }
GET where {token} is your unique token
/oauth/v1/token/{token}
returns { username: joe, permissions['page:admin','users:full'], expires: 123456}
DELETE pass the {token}
/oauth/v1/token/revoke
replies with 200 OK
and an empty body.
Now, how it works:
token
, which the client stores in something like a cookie.GET /resource HTTP/1.1
Host: server.example.com Authorization: Bearer mF_9.B5f-4.1JqM
Your resource server contacts the Slim API on the back-end to determine your permissions. The server then decides what you're allowed to see.
If you don't like sending it as a header, see section 2.2, which describes how to send it in the body, or section 2.3 which sends it as a URI query.
These obviously do not need to be different servers. You can implement it how you wish.