7

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?

3 Answers 3

8

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.
Sign up to request clarification or add additional context in comments.

Comments

1

AuthComponent::login() creates a session variable that stores the user data, so say you had data that was something like.

$data = array('User' => array('id' => 1, 'username' => 'johndoe'));

Then you would use

$this->Auth->login($data);

And access the data with

$this->Auth->user('User');

To get the user id

$this->Auth->user('User.id');

In your AppControllers beforefilter put $this->Auth->deny(); that will deny all actions to someone who is not logged in. Then in each controllers before filter you want to $this->Auth->allow(array('view')); 'view' being the name of an action you want to be public.

http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html

1 Comment

Thank you for your answer. I was kinda wondering how do I authenticate on each action since a mobile app using the API wont be able to maintain a session
1

Cakephp 2.X, After lots of research about this on internet I did not find any satisfactory answer So I found a way myself to do this. May be this answer will help some folks in future. This answer is only applicable for REST API's in cake php.

Add following line in your logic action of REST API before checking for the $this->Auth->login().

 $this->request->data['User'] = $this->request->data ; 
 if($this->Auth->login()){
    echo "Hurray You are logged In from REST API.";
 }
 else
 {
    throw new UnauthorizedException(__('You don\'t belong here.'));
 }

Desciption : As @threeve said in one of the answers that $this->Auth->login() does not do any authentication itself. but rather creates the Auth.User array in your session. For Authentication we require our $this->request->data to be inside User array since User is the model which will check the Credentials in Database. Therefore we have to pass the data to Auth as it is required when not using REST API's. Rest of the things will be handled by Cake and Auth itself.

Any enhancements or suggestions on this answer are most welcome.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.