Summary: I've created an app in PHP. It's lead management system for a call center. I now need to allow a partner to be able to add new leads to the app by integrating our app with their proprietary CRM. In short, I guess I need to build an API for my app.
The easiest approach I can think of is a simple HTML post. Would this be considered too insecure? If so, what would be best approach for this type of situation?
Thanks for any help,
Andrew.
Through your quest to build an API, you'll most likely come across some of these. I'm going to outline the concepts that might come in very handy to actually build an API that is usable, and that follows open standards (which, in turn, makes it trivial for third-party to adapt existing code to interact with it).
The first keyword is: SSL. Don't ever think of not using it. This provides a secure socket layer on which communication can happen in a secure fashion, and consequently makes eavesdropping and MitM attacks significantly more difficult to conceive.
No matter what, do not skip on this. Certificates cost less than $60/year, so it is not exactly costly, and can save you a lot in the long run.
In terms of server techs, use what you want. Your main requirement is a webserver that can handle the four common HTTP verbs: GET, POST, PUT, DELETE. I'll explain why in a moment.
This one is the contentious field, as lots of people "think they have a secure way to do so". The answer is simply not true. The point of your authentication is to allow a client to easily authenticate with their credentials, but to prevent a third-party who is not privileged from doing so.
Simply adding an API key to the feed will just lead to someone eventually getting hold of it. I have seen this specific thing so many times that I strongly advise against it, especially as there are significantly easier options.
I'll go over a couple of things, labelling them as (A) or (S) , respectively for Authentication and Signature. Signing is the method used to render your request tamper-proof. Authentication proves who you are.
This technique is used by Amazon for all their S3/AWS APIs, and is a very lightweight method of signing and authenticating a request. I personally find it relatively ingenious.
The basic idea:
This is simple and ingenious. What it guarantees:
This neatly wraps both issues using the same HTTP request at the cost of one reserved GET/POST field. Amazon also requires the presence of a Timestamp in the request, which prevents replay attacks. Neat!
(For the reference: HMAC- ALGO = ALGO( (key XOR PAD) concat ALGO(key XOR PAD2) concat message)
. ALGO can be any hash cipher - SHA256 is preferred for its lightweight nature)
You've probably heard of it. the idea is simple: you get given a key and secret. This allows you to queue up for a temporary token. This token is then used to perform requests.
The main advantage of this is that lots of libraries exist to handle it, both client-side and server-side. The other advantage is that OAuth has two modes of operation: two-legged (server->server without client interaction) and three-legged (client->server->server).
The main drawback is 2 HTTP requests to get a token.
... Leads to replay attacks. don't consider it.
A mixture of methods is a possible things. The HMAC signage is awesome when combined with OAuth, for example!
API endpoints these days follow two main standards: SOAP (XML-RPC), or REST. If you are building an endpoint to post leads, you may as well build the corresponding API to read leads and to delete them for the future.
Your API would therefore take the form:
/my/endpoint/
- GET: gets a list of leads
- POST: creates a new lead
/my/endpoint/ID/
- GET: get lead info
- PUT: modifies lead
- DELETE: deletes the lead
This allows you to future-proof your API conveniently as well.
A HTML post will suffice, that's not a problem. It would be even better if you're able to use HTTPS to ensure the transferred data is encoded, but this isn't critical.
The most common way of securing this kind of API is to provide a shared 'secret' or 'key', which is used to encode a hash. You'll then be able to verify that the request came from a trusted source, but it's up to the user to ensure that they keep the shared key a secret.
eg Users of your API will need to:
// build hash string to be sent with API POST request (use a sensible combination of values)
$string = sprintf('%s.%d.%d.%d', $username, $orderId, $currentTimestamp, $price);
// hash
$encodedString = sha1($string);
// concatenate with shared key
$stringWithKey = sprintf('%s.%s', $encodedString, $sharedKey); // GET KEY FROM SECURE PLACE
// hash again to get hash that will be sent with the POST request
$hash = sha1($stringWithKey);
Then you'll perform the same logic at your end from the POST values provided and verify that their hash matches the hash that you build with the user's shared key.
This is exactly what an API is for. I'd make a unique key per external account and require that API key for each $_GET
or $_POST
transaction that is sent to your server.
Might want to build an API management console while you're at it. Oh and don't forget the separate DB table for the API keys.
When you're done it'll be something like:
You get the idea.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.