Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API Login approach

We are building system that required login information for all pages. the application is designed to be Restful application using codeigniter as Phil Sturgeon library. This library is using API Key only to authorize api calls via sending it with every request over HTTPS connection.

Even if it using 2 way authentication or only API Key. What i am searching for a while is the following scenario:

  • User request the application for the first time (ex: https://www.xyz.com) then it will be redirected to the login page to check credentials
  • User enter the usernam/password and sent it via POST over the https
  • Server check if the information is valid then:

    • API KEY should be provided by the server to the client as a resource identified by this username (Here is the question???!!!)

    • How to send the API Key to the client in a secure way?

      • 1) Could i use session-cookies and restore the API KEY in a cookie then use this API KEY on every coming request (This is violent the Stateless of the Rest and i don't sure if it securely enough).
      • 2) Actually i don't know other options :) it's your turn if you could help

If you could give an example it would be a great help as i found and read lots of articles

:)

like image 567
ahmedsaber111 Avatar asked Jun 25 '13 13:06

ahmedsaber111


1 Answers

Since the connection is HTTPS, anything you send over the wire is secure (theoretically and provided you aren't being mitm'd). Not sure if the whole API is served over HTTPS (you didn't specify), so even though you could return the key as part of the login (while still under the umbrella of HTTPS), if the rest of the api isn't HTTPS, the key could be sniffed on the next request.

Sessions and cookies aren't typically part of a RESTful application; REST is stateless.

Something like a revolving key would be better for non-HTTPS (would work with HTTPS too). You login via HTTPS, server returns the api key, you use it on the next request, server returns new api key, you use it on the next request and so on. While it's better than a single api key over non-HTTPS, it's not perfect. If someone sniffs the response from one of the subsequent requests and you don't end up consuming that key, they can use it. This shrinks the attack vector to a non-HTTPS response from server to client since if a request from client to server is sniffed, the api key will have already been consumed by your legitimate request. However, more should be done to secure the api if you aren't serving it over HTTPS.

If it were me, I'd look into request signing + https. There's some talk of request signing here: https://stackoverflow.com/a/8567909/183254

There's also some info on digest auth at the Securing the API section of http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/

A pseudo-code example js function on the client

function get_calendar(){
    var key = $('#api_key').value();
    $.ajax({
        type: 'get',
        url: '/index.php/api/calendar?key=' + key,
        success: function(response){
            // show calendar
            // ...
            // set received api key in hidden field with id api_key
            $('#api_key').value(response.api_key)
        }
    })
}

Example controller method:

function calendar_get($api_key = ''){
    if($api_key_matches){//verify incoming api key
        $r = array();
        $r['calendar'] = $this->some_model->get_calendar();
        $r['api_key'] = $this->_generate_api_key();// generate or get api key
     }
     $this->response($r);
}
like image 131
stormdrain Avatar answered Nov 04 '22 15:11

stormdrain