You should look into request signing. A great example is Amazon's S3 REST API.
The overview is actually pretty straightforward. The user has two important pieces of information to use your API, a public user id and a private API Key. They send the public id with the request, and use the private key to sign the request. The receiving server looks up the user's key and decides if the signed request is valid. The flow is something like this:
- User joins your service and gets a user id (e.g. 123) and an API
key.
- User wants to make a request to your API service to update their email address, so they need to send a request to your API, perhaps to
/user/update?email=new@example.com
.
- In order to make it possible to verify the request, the user adds the user id and a signature to the call, so the call becomes
/user/update?email=new@example.com&userid=123&sig=some_generated_string
- The server receives the call, sees that it's from userid=123, and looks up the API key for that user. It then replicates the steps to create the signature from the data, and if the signature matches, the
request is valid.
This methodology ensures the API key is never sent as part of the communication.
Take a look at PHP's hash_hmac() function, it's popular for sending signed requests. Generally you get the user to do something like put all the parameters into an array, sort alphabetically, concatenate into a string and then hash_hmac
that string to get the sig. In this example you might do:
$sig = hash_hmac("sha256",$params['email'].$params['userid'],$API_KEY)
Then add that $sig
onto the REST url as mentioned above.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…