So I have this idea for a very simple service that will provide an API and I know how to write REST-ish APIs in PHP but everything I ever done has been freely accessible. For this one I'd like to provide access via either a key/secret pair or basic http auth.
I have no idea how to do either.
It all works through HTTP headers in some form or another. A normal login procedure usually uses cookies, so there's the request header Cookie: FOO=owiegwoeugiaweg
being sent which the server picks up on. You can do the same for APIs, but it's not usually the best thing to do.
Better is some form of authorization using certain header fields like the Authorization
header:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
This header can contain anything you want. You can use some custom password hashing/key exchange/whatever algorithm and require the client to send this information in the Authorization
header. You could also come up with any custom header of your own, if you like.
A good way to RESTfully authenticate requests is to use request signing. The algorithm for that is up to you, but should include at least the current time, the request body and a user specific key, which is hashed together to form a signature.
headers:
Date: Thu, 20 Oct 2011 04:00:48 GMT
Authorization: MySchema user123:oiquwetfp32900fjp0q93t1039
where:
Date = timestamp, must be within 15 mins of server time
Authorization = MySchema USERNAME:SIGNATURE
SIGNATURE = sha1( Date + REQUEST BODY + PASSKEY )
This way you're essentially sending the user's passkey with every request, but scrambled in a way that's non-reversible, unique for every request, yet confirmable by the server by repeating the same operations (checking for valid timestamp, hashing the Date header + request body + user's passkey). There used to be good documentation that explained this process in detail for Amazon Web Services, but I can't find it right now. Try researching "request signing" for more information.
On the server side you can find these HTTP headers in the $_SERVER
array. The raw request body you can get via file_get_contents('php://input')
.