xpepermint
xpepermint

Reputation: 36243

REST user authentication

OK... the basic idea is to have SERVER and CLIENT physically separated (two systems).

My idea is to build a stand-alone web service (REST, XML, API-KEY) that will provide

  1. Authentication: User login, logout
  2. Data: Get list of products

Then I will create clients in different languages (Flash, PHP, JavaScript). Data will be served only to authenticated users.

Tipical communication for user to get list of products will be:

  1. (1 request) Login / start session
  2. (1 request) Get list of products
  3. (1 request) Get list of products
  4. ...

OK... Now the problem I have is the user session. Say we want to build Javascript client, we actually have to create PHP client that will communicate with REST (PHP knows about REST API-KEY) and will forward info to Javascript (CLIENT) right? User will login through PHP to REST server right and then request data through PHP to REST server?

Questions:

Upvotes: 5

Views: 13635

Answers (5)

broadband
broadband

Reputation: 3488

I'm facing the same problem. I used restserver in php. Ofcourse the traffic goes over SSL connection.

When I would like to get information about certain user I must authenticate first to the rest server before I can get his info. I would like to know any better approaches?

Similar post: RESTful Authentication Good resource is also OAuth2. Also Google uses oauth:

OAuth 2.0 is a new, simplified authorization protocol for all Google APIs. OAuth 2.0 relies on SSL for security instead of requiring your application to do cryptographic signing directly. This protocol allows your application to request access to data associated with a user's Google Account.

When application uses this: http://restserver/user/login and let's say that the authentication went ok, the application itself creates session like this:

Rest client/Application

    public function login() {

    .... form_validation

    // get restserver salt so we can send hashed password
    $message = $this->rest->get('https://restserver/user/salt');

    if($message['status_code'] !== '0') 
      exit;       

    $data = array(
      'username'  => $this->input->post('username'),
      'password'   => prepare_password_salt($this->input->post('password'), $message['salt'])
    );      

    // authenticate with restserver, check if the user and password exist
    $msg = $this->rest->post('https://restserver/user/login', $data);

    if($msg['status_code'] === '0')
    {
      // make session
      $session_data = array(
        'logged_in'     => true,
        'username'    =>  $data['username']
      );

      $this->session->set_userdata($session_data);
      redirect(base_url() . 'some_page');

Rest Server

/**
 * http://restserver/user POST 
 * - insert new user
 *
 * http://restserver/user/id PUT
 * - update existing user
 * 
 * http://restserver/user/login POST
 * - check if username exists and the password match
 * 
 * - return true on success login
 * - return false on failure
 *
 * http://restserver/user/id/hashed_pass GET
 * again client gets salt and then send hashed_pass
 * - return array(
 *   'username' ..
 *   'email' .... 
 *   .. other information
 * );
 * or we could use some access token but that means that the restserver
 * must save token for each user for some time and then delete
 *
 * HTTP server Allowed methods: GET, POST, PUT
 * HTTP server disallowed methods: DELETE
**/

class User extends Rest_Controller
{
  public function __construct()
  {
    parent::__construct();
    $this->load->library('form_validation');
  }

  /**
   * Check username and password with database.
   * 
   * @link /
   * @param $_POST['username'] (string)
   * @param $_POST['password'] (string - sha1(password . salt)) 
   * @return array which contains
   *                array['status_code']
   *                array['status']               
   *                status_code 0 means that login was successful
   *                status_code 1 means that username or password is incorrect
   */
   public function login_post()
   {
     $this->load->model('User_Model', 'user_model');

     $this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[3]|max_length[64]');
     $this->form_validation->set_rules('password', 'Password', 'trim|required|exact_length[40]');

     if($this->form_validation->run() === true)
     {
       // check with the database
       if($this->user_model->authenticate($this->input->post('username'), $this->input->post('password')))
       {
         // update user last_login field
         $this->user_model->updateLogin($this->input->post('username'));

         $message = array(
           'status_code'    => '0',
           'status'     => 'Login ok.'
         );     
       }
       else
       {
         $message = array(
           'status_code'    => '1',
           'status'     => 'Username or password is incorrect.'
         );
       }
     }
     $this->response($message, 200);
   }

Upvotes: 0

Darrel Miller
Darrel Miller

Reputation: 142044

A RESTful interface does not store any information about a particular user's session. It is the client's job to maintain the information about what it is doing.

Authenticate the user on every request by providing information in the Authorization HTTP header. IF this becomes a performance problem, then look at alternative solutions to optimize perf.

Upvotes: 7

TML
TML

Reputation: 12966

To your first question: XmlHttpRequest requests to a service will still pass along cookies, which can be used to propagate a session ID. You can even (assuming the enduser's browser supports it) mark cookies as 'HttpOnly' to reduce your XSS footprint. See Jeff Atwood's article for some detail on that.

Upvotes: 4

Martijn Laarman
Martijn Laarman

Reputation: 13536

You don't need PHP to store an API-KEY if you make your client classes in javascript smart enough to append the API-KEY (loaded when logging in) into the headers of each XmlHttpRequest your class will spawn.

Also it might be good to note that API-KEY does not necessary mean authentication key.

Upvotes: 0

Ciaran McNulty
Ciaran McNulty

Reputation: 18848

You should probably use HTTP authentication for the user auth, and so not need to do any sort of session management.

Upvotes: 1

Related Questions