What I did
The CakePHP version is 2.2.3
I used this part of the Cookbook to create my authentication: Link
After i was finished, i changed the fields to email and password (in AppController.php):
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'Form' => array('userModel' => 'User', 'fields' => array('username' => 'email', 'password' => 'password'))
),
'loginRedirect' => array('controller' => 'twitter', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
'authorize' => array('Controller')
)
);
What happened
When i log in with my credentials, it redirects me to the loggedin page, even when the credentials aren't correct!
I hope someone can help me with the problem.
Thanks in advance!
EDIT:
Login now works as far as i can see! But the logout doesnt work. It doesnt remove my session.
You are passing something to $this->Auth->login($something). The code has changed since 1.x and anything passed to this method will cause the user to be logged in.
You should call $this->Auth->login() with no parameters
Related
After logging a user in, I want to redirect them back to where they came from but It's not working properly in CakePHP 3.5. Here are the required info's to help me figure out this problem.
URL while login(session time out),
http://dev.scys.com/db/admin?redirect=%2Fadmin%2Fstatuses
This is my Auth config,
$this->loadComponent('Auth', [
'loginAction' => ['controller' => 'Admins', 'action' => 'login'],
'loginRedirect' => ['controller' => 'Admins', 'action' => 'index'],
'logoutRedirect' => ['controller' => 'Admins', 'action' => 'login'],
'unauthorizedRedirect' => $this->referer(),
'authenticate' => [
'Form' => [
'finder' => 'auth',
'userModel' => 'Admins',
'fields' => ['username' => 'username', 'password' => 'password']
]
]
]);
And in the Login method/action
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
More Points
I have also tried $this->redirect($this->request->getQuery('redirect'));
Am I missing anything or something else I have to add to work this out :(
I figured out my mistake,
Actually, I was using for action URL like,
$this->Form->create(NULL, ['url'=> ['controller' => 'Admins', 'action' => 'login'],'style'=>'display: block;');
Because of this, the URL became "admins/login" and the redirect query string get removed that's why the problem occurred, because "$this->redirect($this->Auth->redirectUrl());" didn't find any redirect query string(as per the case 1), so it uses $this->Auth->config('loginRedirect');(as per case 2).
Then I solve it by removing the URL key and value from the form create option parameter.
AclNode::node() - Couldn't find Aro node identified by "Array ( [Aro0.model] => User [Aro0.foreign_key] => 1 ) "
Error: An Internal Error Has Occurred.
Stack Trace
My model name is Admin not user, I have set it in the Auth component configurations
public $components = array('Acl',
'Auth' => array(
'loginRedirect' => array('controller' => 'admins', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'admins', 'action' => 'login'),
'loginAction' => array('controller' => 'admins','action' => 'login'),
'authError' => '<font color="red">Did you really think you are allowed to see that? If yes then login!</font>',
'authenticate' => array(
'Form' => array(
'userModel' => 'Admin',
'fields' => array('username' => 'username', 'password' => 'password')
)
)
), 'Session', 'Email');
I don't know how it is User not Admin in the error.
Thanks in advance.
Please realise that Authentication is not the same as Access Control, although you properly configured your AuthComponent (Form) authentication to use the Admin model, the ACL may still be trying to access the User model.
For more information, please refer to the manual here;
http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#assigning-permissions
And here;
http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html#acts-as-a-requester
Especially, the 'model' column when assigning permissions and the section on 'requester'.
I realise this is not a full answer, I don't have the right examples at hand here, but maybe these suggestions will help you to find the solution.
I have a strange issue going on as I try to learn and program website using CakePHP 2.0. I have worked in the past with version 1.3 but never seen this problem before. I am running the Simple Authentication and Authorization Application tutorial from the Cookbook (p.638) and I have checked and doubled checked to make sure it is the same.
The issue I am having is that when I call /users/login and fill out the form with bogus info or simply leave it empty. Auth logs it in and if I do if($this->Auth->user()) I will receive true.
I have given up trying to understand why that is happening. It is strange....
/users/login
public function login(){
if($this->request->is('post')){
if($this->Auth->login($this->request->data)){
$this->redirect($this->Auth->redirect());
}else{
$this->Session->setFlash('Wrong login credentials!', 'default', array('class' => 'notification error closeable'));
}
}
}
// Appcontroller.php ---- Auth configuration
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email')
)
),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'home'),
'authorize' => array('Controller')
)
);
public function isAuthorized($user){
if(isset($user['role']) && $user['role'] === 'admin'){
return true;
}
return false;
}
Ok.Seems like i know what the problem is. Try doing:
if($this->Auth->login())
instead of passing it CakeRequest object.
The reason is:
In 2.0 $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. Maybe thats why you are able to log in without any data.
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email')
)
),
'loginAction' => array('admin' => false, 'controller' => 'users', 'action' => 'login')
'logoutRedirect' => array('controller' => 'pages', 'action' => 'home'),
'authorize' => array('Controller')
)
);
Also try putting a debug($user); in beginning your isAuthorized method in AppController to see if its not getting a false from there.
I've searched through many posts on stackoverflow for an answer, and prehaps I'm just overlooking something, but I can't seem to get $this->Auth->login() to work. I've tried many different suggestions from other posts. I will try to be as thorough as possible when describing other methods I've tried.
I do have adding a user working. The MD5 hashing is working correctly. I hashed a password and then checked it using miracle salad md5 http://www.miraclesalad.com/webtools/md5.php
I do not use a salt for hashing. I use MD5 without a salt.
The database I'm using is Postgresql 9.0. I know some of the CakePhp magic doesn't work for all databases (or so I've been told).
app/Config/core.php
Configure::write('Security.level', 'medium');
/**
* A random string used in security hashing methods.
*/
Configure::write('Security.salt', '');
I was using Auth->fields to map password to user_password and username to user_name in the DB. user_password and user_name are the columns in the core_users table. I also had in the beforeFilter() method.
$this->Auth->fields = array('username' => 'user_name', 'password' => 'user_password');
app/Controller/AppController.php
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'pages', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home'),
'loginAction' => array('admin' => false, 'controller' => 'CoreUsers', 'action' => 'login'),
/*'fields' => array('password' => 'user_password', 'username' => 'user_name'),*/
'userModel' => 'CoreUser'
)
);
public function beforeFilter() {
Security::setHash('md5');
$this->Auth->allow('login');
//debug($this->Auth);
}
}
I left the debugs in so you can see the order that they are processed and I will show you how they are printed.
app/Controller/CoreUsersController.php
public function login() {
Security::setHash('md5');
//debug($this->Auth);
if ($this->request->is('post')) {
debug(Security::hash($this->Auth->request->data['CoreUser']['user_password']));
debug($this->Auth);
debug(Configure::version());
debug($this->Auth->request->data['CoreUser']['user_password']);
debug($this->Auth->request->data['CoreUser']['user_name']);
if ($this->Auth->login()) {
debug($this->Auth->request->data['CoreUser']['user_password']);
$this->redirect($this->Auth->redirect());
} else {
debug($this->Auth->request->data['CoreUser']['user_password']);
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
}
public function logout() {
$this->redirect($this->Auth->logout());
}
app/Model/CoreUser.php
App::uses('AuthComponent', 'Controller/Component');
class CoreUser extends AppModel{
public $primaryKey = 'user_id';
public $sequence = 'core_user_id_seq';
public $name = 'CoreUser';
public $validate = array(
'user_name' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'User name is required'
)
),
'user_password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Password is required'
)
),
'privilege_id' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Privilege ID is required'
),
'legalValues' => array(
'rule' => array('between',1,4),
'message' => 'Privilege must be between 1 and 4'
)
),
'user_initial' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'User initials is required'
)
),
'email' => array(
'rule' => array('email',true),
'message' => 'Email must have an \'#\' symbol and a domain e.g. .com'
)
);
public function beforeSave() {
Security::setHash('md5');
if (isset($this->data[$this->alias]['user_password'])) {
$this->data[$this->alias]['user_password'] = AuthComponent::password($this->data[$this->alias]['user_password']);
}
return true;
}
}
app/View/CoreUsers/login.ctp
<h3>Login</h3>
<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('CoreUser');?>
<fieldset>
<legend><?php echo __('Please enter your username and password'); ?></legend>
<?php
echo $this->Form->input('user_name');
echo $this->Form->input('user_password');
?>
</fieldset>
<?php echo $this->Form->end(__('Login'));?>
</div>
Debug output
All of these are from the CoreUsersController and going in order in which they are processed.
Hashed password. This is the same as what is in the DB, when I added the user.
'098f6bcd4621d373cade4e832627b4f6'
The Auth object
object(AuthComponent) {
components => array(
(int) 0 => 'Session',
(int) 1 => 'RequestHandler'
)
authenticate => array(
(int) 0 => 'Form'
)
authorize => false
ajaxLogin => null
flash => array(
'element' => 'default',
'key' => 'auth',
'params' => array()
)
loginAction => array(
'admin' => false,
'controller' => 'CoreUsers',
'action' => 'login'
)
loginRedirect => array(
'controller' => 'pages',
'action' => 'index'
)
logoutRedirect => array(
'controller' => 'pages',
'action' => 'display',
(int) 0 => 'home'
)
authError => 'You are not authorized to access that location.'
allowedActions => array(
(int) 0 => 'login'
)
request => object(CakeRequest) {
params => array(
'plugin' => null,
'controller' => 'CoreUsers',
'action' => 'login',
'named' => array(),
'pass' => array()
)
data => array(
'CoreUser' => array(
'user_name' => 'testy5',
'user_password' => 'test'
)
)
query => array()
url => 'CoreUsers/login'
base => '/cpm_v2_dev'
webroot => '/cpm_v2_dev/'
here => '/cpm_v2_dev/CoreUsers/login'
}
response => object(CakeResponse) {
}
settings => array(
'loginRedirect' => array(
'controller' => 'pages',
'action' => 'index'
),
'logoutRedirect' => array(
'controller' => 'pages',
'action' => 'display',
(int) 0 => 'home'
),
'loginAction' => array(
'admin' => false,
'controller' => 'CoreUsers',
'action' => 'login'
),
'userModel' => 'CoreUser'
)
userModel => 'CoreUser'
}
Version of CakePHP
'2.1.0'
Password before login() is called
'test'
Username before login() is called
'testy5'
Password after login() is called
'test'
Here is a quick list of things that I've read in other stackoverflow post that I've tried. Let me know if you need to me to elaborate.
1) I mapped username and password to the fields in the DB. It's where the comments are for fields. I also tried doing it in the beforeFilter() method. Using:
$this->Auth->fields = array('username' => 'user_name', 'password' => 'user_password');
In the login view the form was created as such:
$this->Form->input('username');
$this->Form->input('password');
2) I tried hashing the password manually before login like so:
$this->Auth->request->data['CoreUser']['password'] = Security::hash($this->Auth->request->data['CoreUser']['password'])
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
}
EDIT0
3) I just tried doing this as recommended by CakePHP 2.0 Auth Login not working
My AuthComponent now looks like this:
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'Form' => array(
'userModel' => 'CoreUser',
'fields' => array(
'username' => 'user_name',
'password' => 'user_password'
)
)
),
'loginRedirect' => array('controller' => 'pages', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home'),
'loginAction' => array('admin' => false, 'controller' => 'CoreUsers', 'action' => 'login')
)
);
I apologize if I didn't elaborate enough, or I made a mistake. I've been working on this for a couple of days and it has really drained me. I appreciate any help I may receive. Thanks!
What I ended up doing to solve this issue was following the tutorial exactly as CakePHP has it. I also upgraded to 2.1.2. I was running 2.1.0.
http://book.cakephp.org/2.0/en/tutorials-and-examples/blog-auth-example/auth.html
Then I slowly added the configurations I needed. For information about the Auth component I referenced:
http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
Really what my problem was poor troubleshooting. I would make a bunch of changes rather than one at a time. I had my login.ctp view two different ways
$this->Form->input('username');
$this->Form->input('password');
and now it looks like this:
echo $this->Form->input('user_name');
echo $this->Form->Label('Password');
echo $this->Form->password('user_password');
The second version works.
EDIT0:
This is very important. Without a call to the AppController parent the login will not work.
class CoreUsersController extends AppController{
public $helpers = array('Html','Form');
public function beforeFilter() {
parent::beforeFilter();
}
The revision for the Auth component works:
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'Form' => array(
'userModel' => 'CoreUser',
'fields' => array(
'username' => 'user_name',
'password' => 'user_password'
)
)
),
'loginRedirect' => array('controller' => 'pages', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home'),
'loginAction' => array('admin' => false, 'controller' => 'CoreUsers', 'action' => 'login')
)
);
My salt is still an empty string:
Configure::write('Security.salt', '');
Setting the md5 hash is only needed in one place. It's not needed in beforeSave() in the model:
public function beforeFilter() {
Security::setHash('md5');
$this->Auth->allow('login','add');
}
beforeSave():
public function beforeSave() {
if (isset($this->data[$this->alias]['user_password'])) {
$this->data[$this->alias]['user_password'] = AuthComponent::password($this->data[$this->alias]['user_password']);
}
return true;
}
If you added the user directly in the db, the that's the problem. Even though you have an empty string in the config, it' using that in the salt algorithm rather than not using a salt. (This is probably a bad idea, but that's another issue).
Also, the Auth->password function is a wrapper for Security::hash() where the salt is always used. Use Security::hash($password, 'md5', false) instead. That will no salt the password when you save the user. However you will probably need to configure your Auth/login function to login without checking for a salt.
I'm positive that your problem is with the way you have configure Auth...the should work fine with your db.
I had the same error, I did a copy of a cakephp project and couldn't login on the new one. After weeks of searching for a correct answer I found that all I had to do was to change permissions on tmp folder. For an unknown reason when I copy folders some of them where copied with read only permissions.
I'm using a login with a scope to ensure that the user account is active. If the login fails how can i tell if it failed because the email was not matched or if the accounts wasn't activated?
Also, i didn't understand all of the documentation in the cakephp cookbooks, could you please look at my auth section in my components array?
The Email field in the html table and sql table are called 'AccountEmail'
The Password field in the html table and sql table are called 'AccountPassword'
The row in the sql table for active accounts is called 'AccountActive' and is an int type with a value of 0 if the user is not active and 1 if it is active.
'Auth' => array(
'logoutRedirect' => array('controller' => 'Accounts', 'action' => 'login'),
'authError' => 'You can\'t Access That Page',
'authorize' => array('Controller'),
'fields' => array('AccountEmail' => 'AccountEmail', 'AccountPassword' => 'AccountPassword'),
'scope' => array('AccountActive' => '1')
)
You're missing which authentication handler to use and your fields configuration was wrong.
I'll assume you want to use a form to login:
/**
* Auth component configuration
*/
public $components = array(
'Auth'=> array(
'logoutRedirect' => array(
'controller' => 'Accounts',
'action' => 'login'
),
'authError' => 'You can\'t Access That Page',
'authorize' => array('Controller'),
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'AccountEmail',
'password' => 'AccountPassword'
),
'scope' => array('AccountActive' => '1')
)
)
)
);