Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP Authentication on REST API

So I'm creating a REST API for a web app I'm developing, and I know the basic ways for authentication are either sending the credentials on each request or sending a token.

Since I have never used token before, I think I may send the credentials for each request. The point is I can't find any examples on how to handle this in the controller. Would it be something like this?

public function api_index() {
    if(!$this->Auth->login()) return;

    $this->set(array(
        'models' => $this->Model->find('all'),
        '_serialize' => array('models')
    ));
}

I don't really think this is the way AuthComponent::login() works, can I get some directions here please?

like image 215
Christopher Francisco Avatar asked Feb 13 '14 04:02

Christopher Francisco


1 Answers

Alright, first a clarification about how AuthComponent::login works. In Cake 2.x that method does not do any authentication, but rather creates the Auth.User array in your session. You need to implement the actual authentication yourself (the User model is a natural place to do this). A basic authentication method might look like this:

App::uses('AuthComponent', 'Controller/Component');
public function authenticate($data) {
    $user = $this->find('first', array(
        'conditions' => array('User.login' => $data['login']),
    ));
    if($user['User']['password'] !== AuthComponent::password($data['password']) {
        return false;
    }

    unset($user['User']['password']);  // don't forget this part
    return $user;
    // the reason I return the user is so I can pass it to Authcomponent::login if desired
}

Now you can use this from any controller as long as the User model is loaded. You may be aware that you can load it by calling Controller::loadModel('User').

If you want to authenticate every request, then you should then put in the beforeFilter method of AppController:

public function beforeFilter() {
    $this->loadModel('User');
    if(!$this->User->authenticate($this->request->data)) {
        throw new UnauthorizedException(__('You don\'t belong here.'));
    }
}

All of the above assumes that you pass POST values for login and password every time. I think token authentication is definitely the better way to go, but for getting up and running this should work. Some downsides include sending password in cleartext (unless you require ssl) every request and the probably high cpu usage of the hashing algorithm each time. Nevertheless, I hope this gives you a better idea of how to do authentication with cakephp.

Let me know if something needs clarifying.

Update: Since posting this, I found out that you can actually use AuthComponent::login with no parameters, but I am not a fan of doing so. From the CakePHP documentation:

In 2.x $this->Auth->login($this->request->data) will log the user in with 
 whatever data is posted, whereas in 1.3 $this->Auth->login($this->data) 
 would try to identify the user first and only log in when successful.
like image 85
trey-jones Avatar answered Nov 05 '22 08:11

trey-jones