3

Related to this question - with one difference.

Is it possible to set a hashed password for a user? I'm able to save the user just fine - but when I pass the already hashed password like $user->password it doesn't set the password. I'm not seeing anything within $user->getErrors(), it's just a blank array. Any ideas?

3
  • Why set the already hashed password when it's hashed for you? Is it from an import? If so, you need to make sure the has is the same and import it manually into the database, but that starts leaping into dangerous territory. Jul 22, 2014 at 11:36
  • That's right - it's importing from an external system to synchronise passwords. I don't have access to the users raw password, just the hashed password which is hashed using the same password hashing approach as Craft utilises. So it's not possible to save a hashed password without hitting the database directly?
    – Adam
    Jul 22, 2014 at 11:38
  • As far as I know. I would shoot a support ticket to Pixel & Tonic, and post their answer to your own question. Jul 22, 2014 at 11:50

1 Answer 1

4

There’s no API for it; you would need to save it to the database directly.

If any of the passwords are known to you, you should probably start by manually pasting that hashed password into your account’s password column, and verify that it’s actually going to work. Even if the old site was also using mcrypt, it’s still pretty unlikely that they get hashed the exact same way (different salts, etc.).

If it doesn’t work out, and you really don’t want to require everyone to reset their passwords, you could save all of your hashed passwords in a separate table, and write your own "login" controller action using a plugin. That controller action could:

  • grab the user by their given username/email

    $loginName = craft()->request->getPost('loginName');
    $user = craft()->users->getUserByUsernameOrEmail($loginName);
    
  • see if that user has a row in your old hashed passwords table

  • if so, fetch their password from post...

    $password = craft()->request->getPost('password');
    
  • hash that password using the old site’s exact hashing method

  • if the hashed password matches the one in the table...
  • save the posted password on the user account

    $user->newPassword = $password;
    craft()->users->changePassword($user);
    
  • delete the user’s row in the old hashed passwords table (so we're only doing this once per user)

  • log the user in

    craft()->userSession->login($loginName, $password);
    

(See craft/app/controllers/UsersController.php - actionLogin() for a full code example of login().)

2
  • 1
    Thanks for the response. Yeah they do work between the two systems, we've got that all working great. Crafts hashing system has been matched on the other side so users can use the same password between the two sites for a single sign-on set up. So it's less about importing a heap of existing users from another site, and the risk of them having to reset passwords, and more about keeping everything in sync.
    – Adam
    Jul 22, 2014 at 13:06
  • Got it working with db->createCommand(). Thanks!
    – Adam
    Jul 22, 2014 at 17:09

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.