Bulk password updates in Laravel
I have looked at a lot of bulk assignment questions and none of them seem to tackle the problem I am having. I am dealing with a legacy system that stores ~ 350K text passwords in it. I am rebuilding the system for Laravel 4, so I need to use Laravel's password hashing system on all of these entries. I tried:
$users = User::where(DB::raw('length(password)'), '<', 60)->get();
foreach($users as $user)
{
$user->password = Hash::make($user->password);
$user->save();
}
What a job, but it was outrageous at times and I don't want to wait a few days to update all of these records. (The DB is remote, so there is a lot of extra latency in the message.)
I was hoping I could do something like:
DB::table('users')->where(DB::raw('length(password)'), '<', 60)
->update(['password'=>????]);
In the Laravel docs, this is similar to the syntax I would use, but I have no idea what I am going to do with ???? part.
Any help is greatly appreciated! -Erik
You have to go through them - there is no other way. You need to compute a unique salted hash for each open password.
The reason it takes an "outrageous amount of time" is because hashing is expensive. You didn't notice this for 1-2 hashes. But you'll be behind 350k hashes.
It is similar to Bitcoin mining - except that you are not paid this time.
Edit: also - if users could have password length> 60 in "clear text" on your old system - you should still use them in a 60 length hash form if you plan on using the Laravel Auth system - because it will auto hash password when compared with the database.
Answering an old question but came across an almost identical problem.
To avoid three days of downtime, what I ended up with was:
- Temporarily presence of a column password_tmp with a password in text format
- Extended EloquentUserProvider with my own LegacyUserProvider and replaced the validateCredentials method
- If the user is logged in and their password was empty, he tested the password against password_tmp instead. If that was correct, he registered the user and then hashed and saved the password.
- In the background I had a set of running queues that logged in and grabbed users with an empty password column and hashing password_tmp
- Then, a few days later, when all the old passwords were replaced, the dropdown password_tmp
Laravel uses bcrypt
for hashing. bcrypt
specially designed to be slow as a security measure - it prevents an attacker from brute force authorization by trying millions or billions of passwords quickly until you find a match.