My auth component has been working fine for the past year. I was logged into my site about two hours ago and made a single minor change. I got off for those two hours and since I've returned about a half hour ago, I have been unable to log into my site. The error message says the username/password combination is incorrect. I thought somehow the values got changed in my database or that my browser had autosaved an old password so just to be sure I updated the password in my database with it's appropriate md5 hashed value and I tried it again in my browser. It still did not work.
I emptied my cache (which is something I do quite often any way) because I was suggested to do so from this post but this too did not work (nor did it help the poster of that question). That person's solution of having added something to the view file that broke the database connection does not apply to me because I did not change any of the view files. Nor have I changed the user model or app controller. The ONLY thing I changed during the time I was on earlier was that I edited the UsersController online() action. I have since changed it back. In fact, I went into my site backup utility and restored all controller and model files to their latest backup which was 2 days ago when everything was working. Still no affect.
I cannot log into any of the accounts I have registered. I even unhashed one of the passwords in the database and tried logging in with that account but that didn't work either.
AppController
//I HAVE NOT CHANGED THIS IN SEVERAL MONTHS
public $helpers = array('Form', 'Html', 'Custom', 'Time', 'Js', 'Cache');
public $components = array('CustomPage', 'Session', 'CustomUser',
'Auth' => array(
'autoRedirect' => false,
'loginAction' => array('controller' => 'users', 'action' => 'login', 'prefix' => false, 'admin' => false, 'moderate' => false),
'loginRedirect' => array('prefix' => false, 'admin' => false, 'moderate' => false, 'controller' => 'account', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'index', 'prefix' => false, 'admin' => false, 'moderate' => false),
'authError' => "You can't access that page",
'authorize' => array('Controller')
)
); // components
public function isAuthorized($user) {
return true;
}
UsersController
// DID NOT CHANGE FOLLOWING ACTION
public function login() {
if ($this->Session->read('Auth.User')) {
$this->Session->setFlash('You are already logged in');
$this->redirect(array('controller' => 'account', 'action' => 'index'));
}
$this->layout = "simple";
$this->set('title_for_layout', 'Login');
if ($this->request->is('post')) {
$this->User->UsersOnline->deleteAll(array('UsersOnline.session' => $this->viewVars['session_session']), false);
if ($this->Auth->login()) { // check user is logged in
$this->User->id = $this->Auth->user('id');
$this->User->saveField('last_login', date(Configure::read('Site.date_format'))); // save login time
$this->redirect($this->Auth->redirect()); // redirect to default place
} else {
$this->Session->setFlash('Your username/password combination was incorrect');
}
}
} // end login
// THE FOLLOWING ACTION WAS THE ONLY THING
// THAT WAS CHANGED BUT IT IS NOW BACK TO ORIGINAL VERSION
public function online() {
$page_id = $this->viewVars['page_id'];
$link = $this->viewVars['link'];
// CONTAIN
$this->User->UsersOnline->contain(array(
'User' => array(
'fields' => array(
'User.username', 'User.online'
),
'Avatar' => array(
'fields' => array(
'Avatar.file'
)
)
)
));
if($page_id){
$this->set('users', $this->paginate($this->User->UsersOnline, array('UsersOnline.page_id' => $page_id)));
$this->set('title_for_layout', 'Fans Online');
}
else{
$this->set('title_for_layout', 'Users Online');
$this->set('users', $this->paginate($this->User->UsersOnline));
$this->layout = "default";
}
} // end online action
My user model uses the standard "username" and "password" columns to authenticate a user.
I've added the following code to my UserController login() action and the correct result is printed...
$password = md5($this->request->data['User']['password']);
print_r(
$this->User->find('first',
array(
'User.username' => $this->request->data['User']['username'],
'User.password' => $password
)
)
);
Again, I have restored ALL controller and model files to their state from 2 days ago so I really have no idea what could be causing this.
Edit 1: And now just to be safe, I reverted all my view files back to their latest backup versions from this weekend. This did not fix the issue.
Edit 2: If I debug $this->Auth->login, the result is empty. Why would this be empty all of a sudden if nothing has changed?
Edit 3: My UsersController register() action properly creates a new user and automatically logs that user in.
UsersController
public function register() {
if($this->Session->read('Auth.User')) {
$this->Session->setFlash('You are already registered');
$this->redirect(array('controller' => 'account', 'action' => 'index'));
}
$this->layout = "simple";
$this->set('title_for_layout', 'Register');
if ($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
$id = $this->User->id;
$this->request->data['User'] = array_merge($this->request->data['User'], array('id' => $id));
if($this->Auth->login($this->request->data['User'])){
$this->Session->setFlash(__('Your account has successfully been created and you have logged in'));
$this->redirect(array('controller' => 'account', 'action' => 'index'));
} // end if account created and successful log in
else{
$this->Session->setFlash(__('Your account has successfully been created but you cannot log in'));
} // end else if account created but not logged in
} else {
$this->Session->setFlash(__('Your account could not be created. Please, try again.'));
} // end else if account cannot be created
} // end if method is post
} // end register
Well, I never figured out what the INITIAL issue was but now I found out that reverting all of my changed controller, model, AND view files seem to solve the issue. It still bothers me that I don't know what the initial issue was.
However, I DID discover that after I updated all my passwords in my database to their corresponding md5 hash, that was giving me the ongoing issue. I guess Cake doesn't use md5 which I thought so the passwords weren't being matched properly. So even after reverting all my changed files, the passwords all became incorrect.
If I ever figure out what the original issue was I will update.
It may help to remove all files from tmp/cache and tmp/models
I had the same problem.It was working fine but suddenly after some changes in code that was nothing to do with the login part the login function was not working and deleting the changes I made didnt help and when I searched and find out that you have the same problem and you didnt find what the problem is I figured out that it must be some thing very simple as it didnt give me any error and I suddenly found that when I was editing the user controller file I accidently wrote the ' char in the begining of the file and I removed it and the problem is solved!
Related
In this scenario, OurCustomAuth is currently returning an expected value of false, is reaching the appropriate else, but the users/error path keeps redirecting even though it's been made public and not requiring any authentication.
I've setup the new action:
C:\wamp\myapp\app>Console\cake AclExtras.AclExtras aco_update
Welcome to CakePHP v2.4.9 Console
---------------------------------------------------------------
App : app
Path: C:\wamp\myapp\app\
---------------------------------------------------------------
Created Aco node: controllers/Users/error
Aco Update Complete
In the UsersController, I've added the action to be made public:
public function beforeFilter() {
parent::beforeFilter ();
$this->Auth->allow ('logout', 'error');
}
In AppController, the Auth config:
public $components = array(
'Acl',
'Cookie',
'DebugKit.Toolbar', 'Session',
'Auth' => array(
'authenticate' => array('OurCustomAuth'),
'loginAction' => array('controller' => 'users', 'action' => 'view'),
'authError' => 'Did you really think you are allowed to see that?',
'authorize' => array('Actions' => array('actionPath' => 'controllers'))
)
);
...
public function beforeFilter() {
...
//Auto logging users in if they are not logged in
if (!AuthComponent::user('id')) {
if ($this->Auth->login()) {
//stuff here
} else {
$this->Session->setFlash(__('We could not authenticate you ...'));
return $this->redirect(array('controller' => 'Users', 'action' => 'error'));
}
}
...
}
The error I get in Firefox:
The page isn’t redirecting properly
Firefox has detected that the server is redirecting the request for
this address in a way that will never complete.
Update #1
$this->Auth->login() essentially grabs request headers, that in this case are intentionally wrong, which seems to redirect to the appropriate link. However, /users/error shouldn't cause a redirect as it's excluded from Authentication.
The problem is that you run your login code on every request, ie in the app controllers beforeFilter() method. So when that code redirects you to /users/error because you're not logged in, the code will run again for that controller/action, and redirect you again, and again, and again...
If you need to run this code for every request, then you'll have to check the allowed actions manually, ie the actions allowed via $this->Auth->allow(), and run your code only in case the current action isn't allowed. Check the code of AuthComponent::_isAllowed(), you can easily use that with minimal modifications:
$action = strtolower($this->request->params['action']);
if (!in_array($action, array_map('strtolower', $this->Auth->allowedActions))) {
//Auto logging users in if they are not logged in
if (!AuthComponent::user('id')) {
// ...
}
}
I am facing this weird problem. I am trying to change the default loginRedirect of the admin role from that of normal user.
U have the auth key in the AppController's component variable set up as follows :
'Auth' => array(
'loginRedirect' => array(
'controller' => 'donors',
'action' => 'index'
)
)
Now in the beforeFilter callback I have this set up:
if($this->Auth->user('role') == 'admin'){
$this->Auth->loginRedirect = array(
'controller'=>'users',
'action'=>'admin_index',
'prefix'=>'admin',
'admin'=>true
);
}
However, this does not work and the if condition is never met. I am expecting this to run when the user logs in. If I add an else condition and repeat the same code shown above, it works and the admin is redirect to the desired page.
Can anyone instruct how I am able to do this correctly ? Thanks in advance
If the user is not logged in, $this->Auth->user() will return null. beforeFilter() will run before any action is run, so your login() action has still not been called.
Do the redirecting after $this->Auth->login() has been called and is successful. E.g. in your UsersController::login() action (or whichever action you use to login):
if ($this->Auth->login()) {
if($this->Auth->user('role') == 'admin') {
$this->redirect(array(
'controller'=>'users',
'action'=>'admin_index',
'prefix'=>'admin',
'admin'=>true
);
}
}
Instead of $this->Auth->loginRedirect use $this->redirect(
array('controller' => 'users', 'action' => 'admin_index');
Its less complicated
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
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')
)
);
I had downloaded the plugin from link
https://github.com/CakeDC/users
followed the steps given in the page. I have created the tables 'users' and 'details'. I have also registered the user and verfied the user, but while accessing the link www.mydomain/users/users/login this page is getting redirected to www.mydomain/users/login
which shows missing controller. I am new to cake and for me it is difficult to debug. I would be thank if some one help me.
Thank you for the response.
Yes, I have added the code given in the "cake\libs\controller\app_controller.php" file. In order to test this I have freshly downloaded the core files and setup the files in my local system. I have placed the plugins 'utils', 'search' and 'users' to my app/plugins folder and created the tables.
Now also I am able to register the user but not able to see the login page. ie. "while accessing the link www.mydomain/users/users/login this page is getting redirected to www.mydomain/users/login which shows missing controller".
Please let me know if I am missing anything or I am wrong.
Thank you.
This looks like a problem in the login redirection.
Did you add the beforeFilter() configuration to your app_controller?
if not you may need to add it.
Here is an example of how your app_controller should look like:
<?php
class AppController extends Controller {
var $components = array('RequestHandler', 'Session', 'Auth');
function beforeFilter(){
$this->Auth->fields = array('username' => 'email', 'password' => 'passwd');
$this->Auth->loginAction = array('plugin' => 'users', 'controller' => 'users', 'action' => 'login', 'admin' => false);
$this->Auth->loginRedirect = '/';
$this->Auth->logoutRedirect = '/';
$this->Auth->authError = __('Sorry, but you need to login to access this location.', true);
$this->Auth->loginError = __('Invalid e-mail / password combination. Please try again', true);
$this->Auth->autoRedirect = false;
$this->Auth->userModel = 'Users.User';
$this->Auth->userScope = array('User.active' => 1);
}
}
?>
Remember that the $this->Auth->loginAction MOST contain the 'plugin'=>'users', without it it will go to www.mydomain/users/login instead of www.mydomain/users/users/login