How do I handle authorization to an API written in

2019-04-16 16:54发布

问题:

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.

回答1:

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').