6

I'm building a PHP application from scratch (using Kohana3 framework). I'm going to architect it so that I can use an API to access the data internally. At the same time, I want to eventually offer it to the public.

I plan on using the RESTful access method. However, I'm having a hard time finding clear information on how to properly secure the API. In other words, how do I implement API signatures and access?

Adam Wright
  • 48,938
  • 12
  • 131
  • 152
Andres
  • 5,002
  • 6
  • 31
  • 34

6 Answers6

5

You could try frapi. It will quickly allow you to build your RESTful API, which you can then use for your application, and at a later date expose the same API publicly.

Nalum
  • 4,143
  • 5
  • 38
  • 55
David Gillen
  • 1,172
  • 5
  • 14
  • Wow frapi looks pretty sweet, although their site is far more spartan than it looks once you start clicking around. – Justin Feb 18 '11 at 16:30
2

OAuth would be a good choice. So would a single key/value pair. You might also want to look at Mashape but not entirely sure it fits what you are trying to do.

shadowhand
  • 3,202
  • 19
  • 23
1

Take a look at 3scale (http://www.3scale.net/) to do this - it handles authentication, access control, policies, rate limits etc. and is free for significant traffic. We have a PHP module to plugin to the system to enable these features. (Disclaimer - I work there - but hope it's useful!)

steve
  • 1,978
  • 13
  • 23
1

I think a good place to start would be reading over general information about digital signing. Wikipedia is a great resource http://en.wikipedia.org/wiki/Public_Key_Infrastructure or http://en.wikipedia.org/wiki/X.509.
On a basic level I would give each client a private Key. In the client library I would encrypt the key. When a client makes a request verify that the key is the one that you issued to that particular client.

dm03514
  • 54,664
  • 18
  • 108
  • 145
  • 1
    Yes. This is what I'm trying to understand. Oauth is confusing in the methods of how to implement as a provider within my own application. I would rather do it myself, learn, and then consider using their, ever-changing, libraries. I'm having trouble on the basics. You explained something similar to what I envisioned. Although, sessions and cookies also play a role on keeping requests signed-in. Using delegated sign-in is a whole other problem too. – Andres Feb 18 '11 at 16:50
0

I have made a PHP REST API using CodeIgniter with Basic Authentication, (providing "company id" and "API Key" as username/password). Later we found that it was necessary to provision session keys that were directly related to an API Key, only with an expiration time.

Basically, we queried different types of data in our datastore (nosql variety :) depending on what the "method" was provided in the URL. We accessed this by using the "segment" ability provided by CodeIgniter.

Then we wrapped each response with a "json_encode" that was returned and we also used an HTTPS connection for security.

For the client class we wrapped everything in calls such $client->get_my_data($api_key), with a layer underneath using PHP Libcurl, which works really well to provide the Basic Auth.

Hope this helps,

CURL_GET

    private function curl_get($url, $apikey, $co)
    {
        $curl_handle = curl_init();
        curl_setopt($curl_handle, CURLOPT_URL, $url);
        curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
        curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl_handle, CURLOPT_USERPWD, $co.":".$apikey);
        curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl_handle, CURLOPT_DNS_USE_GLOBAL_CACHE, FALSE);

        $buffer = curl_exec($curl_handle);
        $error = curl_error($curl_handle);
        curl_close($curl_handle);
        // check for success or failure
        if (empty($buffer)) {
        //echo 'Something went wrong :( error: '.$error.'<Br>';
        } else {
        return $buffer;
        }
    }
Doug Molineux
  • 12,283
  • 25
  • 92
  • 144
  • By Client Class, do you mean the main interface that clients talk through with RESTful URLS? Like, client [controller], get_name [method] with URL like: site.com/api/client/123?apikey=12345 which fires $client->get_name('123', apikey)? – Andres Feb 18 '11 at 16:57
  • Thats yes thats right, so then the client can include the class and have access to it inside a php file, I'll update my answer with an example "get" function for CURL. – Doug Molineux Feb 18 '11 at 19:33
0

Your question is a bit bigger than this; but I can offer one small observation about REST.

I have found with REST, that is that it is best to use artificial keys for the underlying data model, rather than natural keys.

For example, consider the RESTfull url: https://server/yourApp/viewUser/1234.html this would show the user with id 1234. However if you used natural keys you might have a URL something like this https://server/yourApp/viewUser/Bob.html or worse if instead of Bob its "Bob X" or "Bob?key=Value". You don't want to have to think about generating invalid URLs.

Justin
  • 4,437
  • 6
  • 32
  • 52
  • Thanks, but not the answer I was looking for. I'm looking for authentication keys... sort of. – Andres Feb 18 '11 at 16:42
  • I didn't understand that part of the frapi either (I don't see where they define what an "API Key" is. I did my access control in terms of subjects and authorizations. You can use HTTP BASIC/SSL or SSL mutual auth to establish a subject ID, and whatever you want for authorization. – Justin Feb 18 '11 at 17:28