CakePHP login function for ajax call - cakephp

So here is situation:
I'm using Js helper to create ajax login form in CakePHP and this is placed in my view:
<?php
$data = $this->Js->get('#UserLoginForm')->serializeForm(array('isForm' => true, 'inline' => true));
$this->Js->get('#UserLoginForm')->event(
'submit',
$this->Js->request(
array ('controller' => 'users', 'action' => 'login'),
array (
'update' => '#messagediv',
'before' => '$("#loading").fadeIn()',
'complete' => '$("#loading").fadeOut()',
'data' => $data,
'async' => true,
'dataExpression'=>true,
'method' => 'POST',
)
)
);
?>
Then below this I have my form included and below form I have:
<?php echo $this->Form->create('User');
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->end('submit);
?>
<?php echo $this->Js->writeBuffer(); ?>
Now I don't know how to make proper function in controller to check for login and redirect if successfull or display error if not..
I was able to make something that check for login and echo 1 if login deatils are correct and echo 0 if not but whenever I try to use redirect in controller function it just load "whole login page" in div #messagediv...
This is how my controller action looks now:
public function login() {
if ($this->request->isAjax()) {
$this->layout = 'ajax';
if ($this->Auth->login()) {
$this->Session->setFlash('Login Successfull');
} else {
$this->Session->setFlash('Login Incorrect');
}
}
}
Can anyone tell me what I'm doing wrong?
So how to redirect after login successfull and how to output error message to #messagediv if wrong username or pw?

If I understand correctly what you're trying to do (load only the flash message and not the whole page), change your action like this:
public function login() {
if ($this->request->isAjax()) {
$this->layout = 'ajax';
if ($this->Auth->login()) {
$this->Session->setFlash('Login Successfull');
$this->redirect('wherever');
} else {
$this->Session->setFlash('Login Incorrect');
$this->render('messagediv');
}
}
}
Then create a View at View/Users/messagediv.ctp that only contains echo $this->Session->flash();
There might be other ways of doing this that might be better, though I'm not sure depending on your exact use for it. This should solve what you're trying to do (if I'm not mistaken).

Try adding RequestHandler to your $components array.
var $components = array("RequestHandler");

Related

CakePHP Auth not re-logging in to the right path

I am having some issues with the CakePHP Auth login. For some reason, instead of the site going to the path i have laid out for it, it looks at the form and goes right to the login function.
To explain, here is my code,
Router File :
Router::connect('/clientlogin', array('controller' => 'pages', 'action' => 'UsersLogin'));
Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
Pages Controller - UsersLogin Function :
public function UsersLogin() {
$this->render('/Pages/LoginForm');
} //End of UsersLogin function
Users Controller - login Function :
public function login() {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Invalid Username Or Password, Please Try Again', 'default', array(), 'bad');
$this->redirect($this->Auth->redirect());
}
} //End of Login function
LoginForm.cpt Code :
echo $this->Session->flash('auth');
echo $this->Form->create('User', array('url'=>'/login', 'id' => 'LoginForm'));
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->submit('Login', array('class' => 'Button'));
echo $this->Form->end();
My main menu in my site has a 'login' button that points to '/clientlogin', which loads the form for my users to login with. However, when the session information expires, the areas of the site which require login to access them push me over to re-login.
But CakePHP is not going to /clientlogin its going to /login - which is not the form but the login controller. Also it dose not matter what I change it to but where ever I point my form is where Cake whats to go. For example, I changed the form to point to /mylogintest or /loginuser and Cake went to these paths instead.
So my main question is, when Cake needs to re auth the session information, how do I make sure it points to my clientform path and not the path laid out in my form.
If I have not been clear or, I have not posted something needed, then please ask me and I will try and fix it.
Many Thanks for any help given
Glenn.
You can change the default login action by passing extra keys into the components. See the code below :
// Pass settings in $components array
public $components = array(
'Auth' => array(
'loginAction' => array(
'controller' => 'pages',
'action' => 'UsersLogin'
)
)
);
I am not sure why you need to create separate action to contain the login form. Usually I'll have the form inside the login action and check the request using $this->request->is('post'). See the Cookbook for more information http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html

cakePhp redirect and Auth doesn't work on server

I have a problem with login on www server. On wamp (local) everything wokrs fine. When I uploded my site on the server, login doesn't work and I see that rediret too. I have login form, after click login it goes to Users controller to login action.
Login action looks like this:
public function login(){
if($this->request->is('post')){
if($this->Auth->login()){
$this->redirect($this->referer());
}
else{
$this->Session->setFlash(__('Wrong username or password'));
$this->redirect($this->referer());
}
}
}
It should redirect both when success or not. It stays on: users/login page. What can be wrong?
AppController:
public $components = array(
'Session',
'Auth'=>array(
'logoutRedirect'=>array('controller'=>'main', 'action'=>'index')
)
);
public function beforeFilter(){
$this->Auth->allow();
}
Form:
<?php
echo $this->Form->create('User', array('action' => 'login'));
echo $this->Form->input('username', array('label'=>__('Username:')));
echo $this->Form->input('password', array('label'=>__('Password:')));
echo $this->Form->end(__('Login'));
?>
There was a white space after ?> on one file.... After 3 hours I found out that that was bad :)

CakePHP SaveAll not working

I can't seem to get my edit class to work. My validation works fine and when I use debug($this->data) after hitting the edit button all the displayed data is perfect, but not updating the tables.
Here is my edit class.
public function edit($id = null) {
if($this->request->is('get')) {
$this->request->data = $this->Bookmark->read(null, $id);
} else {
if($this->Bookmark->saveAll($this->request->data)) {
$this->Session->setFlash('The bookmark has been saved!');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('The bookmark could not be saved. Please, try again.');
}
}
}
Here is the view.
<?php
echo $this->Form->create('Bookmark', array(
'action' => 'edit',
'inputDefaults' => array(
'class' => 'input-text'
)
));
echo $this->Form->inputs(array(
'legend' => false,
'fieldset' => true,
'Bookmark.title',
'Url.url',
'Bookmark.id' => array('type' => 'hidden'),
'Url.id' => array('type' => 'hidden')
));
echo $this->Form->button('Edit');
echo $this->Form->end();
?>
I have updated my edit class, but that still didn't fix my error. What fixed it was the two hidden fields I added to the view.
'Bookmark.id' => array('type' => 'hidden'),
'Url.id' => array('type' => 'hidden')
Not really sure why, but I looked at some other edit views online and tried this and it now works.
Try following this page: http://book.cakephp.org/2.0/en/models/saving-your-data.html
In Cake 2.0.x you should be using $this->request->data, though that's not likely the problem. You'll also see they're not setting the id manually, but allowing the form to do that fom them.
If you try it as the book suggests, and it's still not working, post your new attempt as an Edit to this question.
Each time this happend to me was because of validation error. Check for validation errors like so
echo debug( $this->ModelName->invalidFields() );

How to get Authentication working again in CakePHP 2.0?

After migrating a fully functional Cake 1.3 application to the recently released 2.0 version Authentication has ceased to work.
I've changed the calling of the AuthComponent and the structure of the login action according to the updated 2.0 manual, to no avail. The strange thing is the user is actually validated by $this->Auth->login() as it reaches the part of the login function where the user is redirect to the url set by $this->Auth->redirect(). After that redirect however, $this->Auth->user() returns empty (as well as AuthComponent::user()) and the user isn't logged in by the Auth component.
Cake doesn't throw any error during the process, the flash messages for 'auth' remain empty.
Users are stored in a simple database table containing id, username, email, password and timestamp columns. The passwords are hashed and I've added some users using the new Cake 2.0 methods.
This is the code of AppController.php:
<?php
class AppController extends Controller {
public $helpers = array('Session', 'Html', 'Time', 'Form', 'Text');
public $components = array('Session', 'RequestHandler', 'Auth');
public function beforeFilter() {
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'maps', 'action' => 'index');
$this->Auth->logoutRedirect = array('controller' => 'maps', 'action' => 'index');
}
}
?>
UserController.php:
<?php
class UsersController extends AppController {
public $name = 'Users';
function beforeFilter() {
parent::beforeFilter();
}
function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
}
}
}
function logout() {
$this->redirect($this->Auth->logout());
}
}
?>
User.php model. I've disabled form validation for the time being after I solve this problem:
<?php
class User extends AppModel {
public $name = 'User';
}
?>
The login view:
<?php
echo $this->Form->create('User');
echo $this->Form->input('username', array('label' => 'Username', 'before' => '<p class="input" id="username">', 'after' => '</p>', 'between' => '<br />', 'div' => false));
echo $this->Form->input('password', array('label' => 'Password', 'before' => '<p class="input" id="password">', 'after' => '</p>', 'between' => '<br />', 'div' => false));
echo $this->Form->end('Login');
?>
I also tried to setting some of the Auth features in the $components variable in the AppController, which didn't work as well:
public $components = array(
'Auth'=> array(
'loginAction' => array(
'controller' => 'users',
'action' => 'login',
),
'loginRedirect' => array(
'controller' => 'maps',
'action' => 'index',
),
'authenticate' => array(
'Form' => array(
'fields' => array('username', 'password')
)
)
)
);
What's causing the problem here? Routing maybe? I've commented out all routes except:
require CAKE . 'Config' . DS . 'routes.php';
UPDATE:
After adding some debug statements in the login method in the UsersController I now know $this->Auth->user() is actually populated with the correct user after the call to $this->Auth->login(). After the redirect to another controller the login session is lost completely, however. So I still don't know what's going wrong here.
UPDATE 2
I've restarted the process of migrating by taking my working 1.3 application and running the migration console script on it like I did the last time.
This time I noticed the script stopped because of two errors relating to custom components. Component classes should extend Component now, instead of the 1.3 default: Object.
After fixing these component errors I ran the migration script again (something I neglected to do during the first migration attempt) and implemented the new AuthCompenent call. So far everything seems to be working correctly. Not sure what's different now and what went wrong the first time, as Cake didn't output any error messages.
UPDATE 3
It's getting weirder. I thought I solved it, but after transferring my code to another development machine Auth suddenly stops working. It's working on my main setup, but while testing on another it fails again following the same scenario. I've cleared the cache to be sure, but it still isn't working. Cake doesn't generate any error output.
UPDATE 4
It appears to be a Session problem on my machine. I've just set the Session to be stored in a cookie and suddenly Auth starts working again. Not sure why the default Session isn't working and I don't know where to start debugging in that case.
Only cookie sessions appear to work, defining a database session has the same result as a regular session; Auth stops working.
Try it with use_trans_sid enabled in /Config/core.php:
Configure::write('Session', array(
//'defaults' => 'php'
'defaults' => 'cake',
'cookie' => 'CAKEPHP2',
'ini' => array('session.use_trans_sid' => true)
));
Did you try also to configure the Authentication handler ?
public $components = array(
'Auth'=> array(
'authenticate' => array('Form')
)
);

How to create a ground of checkbox in Cakephp? and how to store it?

I have a field called Hobbies, I wish to store all the hobbies selected by the user to be stored in the database as CSV. How can I do this in Cakephp?
Paste into view (ie, views/users/add.ctp)
<?php echo $form->create('User', array('action' => 'add')) ?>
<?php echo $form->input('User.hobbies', array('type' => 'select',
'multiple' => 'checkbox',
'options' => array('sports' => 'sports',
'movies' => 'movies',
'games' => 'games'))) ?>
<?php echo $form->end('Save') ?>
Paste into Users controller (just a standard save method, nothing special here)
function add() {
if(!empty($this->data)) {
if($this->User->saveAll($this->data, array('validate' => 'first'))) {
$this->Session->setFlash('User saved successfully');
} else {
$this->Session->setFlash('User failed to save');
}
}
}
Paste into User model
function beforeValidate() {
// join hobbies into csv
if(!empty($this->data['User']['hobbies'])) {
$this->data['User']['hobbies'] = join(',', $this->data['User']['hobbies']);
}
return true;
}
Notes:
If you need to separate the hobbies back out when reading the User model, you could use the "afterFind" callback or check out the Serializable Behaviour http://blog.matsimitsu.nl/code/206/serializeable-behavior-for-cakephp that automatically serializes and deserializes whenever you try to add or pull out an array to/from the db.
You could add the beforeValidate code to the beforeSave callback instead, just depends what kind of validation you want to perform. having the code in beforeValidate will let you do a basic notEmpty check, however in beforeSave will mean you can check individual items are present in the array.
References:
http://book.cakephp.org/view/76/Callback-Methods
http://book.cakephp.org/view/189/Automagic-Form-Elements

Resources