CakePHP - Cannot access logged in user's password in Model using Authcomponent::user - cakephp

I started trying out CakePHP a few months ago and I'm now attempting to create a "change password page" for logged in users. I have a form consisting of these fields: current password, new password and new password confirmation. For the current password, I want to validate that it matches the password of the logged in user, as a rule within the user Model. I know that I can get information of the logged in user with this: AuthComponent::user(). However, it provides me every field of the model except the password.
I know that Auth->login() is responsible for setting the session variables for the logged in user, but I'm not sure what I'm doing wrong here that only the password field cannot be accessed:
public function login() {
if ($this->request->is('POST')) {
if($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Your username/password combination was incorrect.');
}
}
}
Here's my login view:
<h2>Login</h2>
<?php
echo $this->Form->create('Promoter');
echo $this->Form->input('username');
echo $this->Form->input('password', array('type' => 'password'));
echo $this->Form->end('Login');?>
I'm using the Promoter model as the user, which i set in the AppController:
public $components = array(
'Auth'=>array(
...
'authenticate' => array(
'Form' => array('userModel' => 'Promoter')
),
'authorize' => array('Controller')
)
);
I can resort to validating the password in the Controller, but that would be giving up :) Please tell me if I need to provide more code to clarify the issue.
Thanks.

You're probably not doing anything wrong, this is most likely a security feature. There is no reason to keep a password in your session.
Secondly, even if it was in session, it would be encrypted (or at least I hope so, if it's not you should change that immediately!). So you still couldn't do a simple comparison.
To compare the old password, you should query your Promoter model, and get the hashed password from there, then hash the old password from your "change password" form, and finally compare the hashed results.

Because cake doesn't store the password in the session:
lib/Cake/Component/Auth/BaseAuthenticate.php line 94
unset($user[$fields['password']]);

Related

Troubles with logging in with a newly created user

I created a CRUD that allows me to create users, societies and schools in a back office.
However, for an unknown reason, I can't log in with a created user with the password I gave him.
Here is my controller (the part where the user is created)
/**
* Creates a new User entity.
*
* #Route("/new", name="user_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$user = new User();
$form = $this->createForm('UserBundle\Form\UserType', $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$password = $this->get('security.password_encoder')->encodePassword($user, $user->getPassword());
$user->setPassword($password);
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_show', array('id' => $user->getId()));
}
return $this->render('user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
}
After registering a new user, when I check it in the fos_user table, I can see that the password has been encrypted. However, if I try to login with the password I used, I simply get "bad credential" from my login form.
I can't figure out why.
Tell me if you need to see another file, I'll update my question
Any idea ?
Thank you in advance
The correct way to create user and set password in FOSUserBundle is the following:
$userManager = $this->container->get('fos_user.user_manager');
$userAdmin = $userManager->createUser();
$userAdmin->setUsername('System');
$userAdmin->setEmail('system#example.com');
$userAdmin->setPlainPassword('test');
$userAdmin->setEnabled(true);
$userManager->updateUser($userAdmin, true);
Password is kept encrypted in database. And to make it harder to bruteforce, database contains an additional field, named salt. You don't store it in your code, that's why it's impossible later to check password. But actually, you don't have to encrypt password and store it in database. User model contains a special method for it, setPlainPassword, which is intended to encrypt password populate both fields salt and password in database with correct values.

cakephp 2.5.7 login->Auth always false even password is correct

I was stuck in this problem for almost a week. Even going through all the solutions in the internet doesn't help me to solve my problem. So I decided to ask my problem here and hope I will get solution.
My problem is why i always get Auth FALSE even my password is correct? I manage to add a new user and it stores the encrypted password, but when I try to login using that username and `password, it displays "Invalid username or password, try again"
Here is my code.
Thank in advance
I had some troubles with this part of cake as well, here is the way that I ended up using which works for me
public function login() {
if ($this->request->is('post')) {
$options = array(
'conditions' => array(
'User.username' => $this->request->data['User']['username'],
'User.password' => Security::hash($this->request->data['User']['password'], 'sha256', true)
),
'fields' => array(
'User.id',
'User.username',
'User.group_id',
// other fields you need
)
);
$userData = $this->User->find('first', $options);
if (!empty($userData) && $this->Auth->login($userData['User'])) {
$this->redirect($this->Auth->redirectUrl());
} else {
$this->Session->setFlash(__('Username, and/or password are incorrect'));
}
}
}
so, the bottom line is to manually check if the user with the given username and password exists, and then login them. Btw, pls pay attention that to login() function I am passing an array like this
array(
'id' => 1,
'email' => 'test#gmail.com',
'group_id' => 2
);
and not
array(
'User' => array(
'id' => 1,
'email' => 'test#gmail.com',
'group_id' => 2
)
);
also, you do not want to pass the password to the login function if you are using cake 2.x, from cake docs
http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#identifying-users-and-logging-them-in
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.
so, first of all no need to pass the password, but you should be careful to check the valid user password before using login because if as it mentioned above, cake will login the user with any data.
About the password hashing part, please be sure you are using the same hashing algorithm with exact same salt (if you use it and you should) that you used during registration.
edit:
try using this in the model's beforeSave
public function beforeSave($options = array()) {
parent::beforeSave($options);
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = Security::hash($this->data[$this->alias]['password'], 'sha256', true);
}
}
For the last thing it is better practice to save a unique salt per user(salt should be saved in db along with user's password). In cake only one application side salt is being used for all passwords, and if the db and the app are compromised attacker can generate just one custom rainbow table for all passwords, but if the salt is unique for each user, then the bad guy should create custom rainbow table for each user separately, which is a lot more work/time/money.

need password and confirm password fields in user/register page drupal 7

I am new to drupal. I want the fields(password, confirm password, roles) from admin/people/create to user/register page.
User can create their account with particular role. How can I achieve that when the user register their account.
By help of this code snippets _form();
The Drupal Form API password_confirm element
$form['pass_fields'] = array(
'#type' => 'password_confirm' ,
'#description' => t('Enter the same password in both fields'),
'#size' => 32,
'#required' => TRUE,
);
To check or auto save user role in _form();:
$role = 'user-role';
array( 'roles' => $roles );
you can use this module https://drupal.org/project/autoassignrole
Also if you unchecked option Require e-mail verification when a visitor creates an account. under Home » Administration » Configuration » People
Then you get password and confirm password fields in user registration form.
I created user-register-form.tpl.php with the following code.
<?php print render($form['account']); ?>
<?php print render($form['form_build_id']); ?>
<?php print render($form['form_id']); ?>
<?php print drupal_render($form['actions']); ?>
I unchecked require e-mail verification link. Using profile2_regpath module i checked the role. It is for when the user creates their accounts the role will automatically assign to the user.

Custom non-username/password based login with CakePHP

The jist of this question is about how to override CakePHP's auth component login function to log a user in based on something other than the default username and password.
So, we're developing a custom login function for one of our partners. Basically, the solution provides online courses to a number of companies who want to provide their clients and/or employees with in house training material.
This particular solution takes a home loan account number and personal identification number and does some algorithm validation and logs the user in. Or at least - that's what it should do.
Currently, the auth component tries to user a particular model to compare username and hashed password. Is there anyway to override this particular behaviour and get the Authcomponent to log the user in using the algorithm (glorified regex check) in a custom function? It should completely ignore the need for a username and password. In addition we won't actually have these account numbers and ID numbers stored anywhere. They will each be checked for certain related patterns.
Cheers
Custom your login with authenticate property :
In your appController
public $components = array(
'Session',
'Auth' => array(
'authError' => "You don't have accès",
'authorize' => array('Controller'),
authenticate' => array(
'Form' => array('userModel' => 'MyUserModel',
'fields' => array('username' => 'numberuser','password' => 'personnalId'),
)
)
);

Why isn't my password hashing?

So, I looked around and checked SO as well. My question similar to this: Why is the CakePHP authentication component not hashing my password? except that I cannot get it to work.
My password is unhashed upon registration.
In my Users Controller:
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('register', 'logout');
$this->Auth->fields = array('username' => 'email', 'password' => 'password');
}
View:
<?php echo $this->Form->create('User'); ?>
<fieldset>
<?php
echo $this->Form->input('email');
echo $this->Form->input('password');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
And I have some validators for the email field. The problem is, the password is being stored as plaintext. I thought
the Auth->fields line should have taken care of this, but it isn't. I know CakePHP only hashes if username and password in the $data are both populated, but I clearly remapped it, so it should have hashed correct?
If you are using CakePHP 2.x, Auth won't hash your password automatically anymore
From the docs at http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
AuthComponent no longer automatically hashes every password it can
find. This was removed because it made a number of common tasks like
validation difficult. You should never store plain text passwords, and
before saving a user record you should always hash the password. You
can use the static AuthComponent::password() to hash passwords before
saving them. This will use the configured hashing strategy for your
application.

Resources