Learn to automatically hash passwords before saving records to the database using PHP's password_hash function.
- [Instructor] Now that we have the basics of our admin class and the PHP pages that we're going to use to manage it, we're ready to talk about how we hash passwords before we storm in the database and we're going to do it using object-oriented programming. You may remember that PHP offers us a function that makes password hashing very easy. It's very secure and it uses best practices. All we have to do is call password_hash and pass in the password to it. That's it. As a second argument, we can specify the kind of algorithm that we should use.
By default, that's going to be PASSWORD_BCRYPT that uses BCRYPT and the blowfish cipher, which is very secure and good for this purpose. So that's all there is to it. We pass in a string to this function and it returns back a hashed version of the password that's suitable for being stored in the database. Now, what I have in mind for the way this is going to work is that we have one property here called password and that's what's going to be set on the form. That's the value that's actually going to be passed into us. It doesn't have a database column, it's just a property on our object.
So let's take a look at admins, here. Look at form fields and you'll see me scroll down here. It's got password, right, so that's what we're going to be passing it is just password. So that value is going to be sent in and, for example, when we create a new object it's going to be in the post parameters, it will become an arg, it will be passed in to the admin object and then, in the admin object, when it constructs it, it's going to set that value, right. So it's going to take the argument password and set it to password. Not hash password.
Hash password is going to be something that's only used internally. This class is going to be able to use it, it's going to be able to encrypt the password and set it, but we're not going to be sending in an encrypted version of the password, right? That's going to happen behind the scenes. So the way that I think we should do that, is let's create a new method here called public function set hash password. So if I call set hash password, it's going to set that value of hash password equal to, and what do we want it to be equal to? We want it to be equal to this password once it's been encrypted.
So we'll call password hash and we'll pass in this password. And we could leave it just like that, but I'm going to go ahead and specify that the algorithm is password bcrypt, just in case that ever changes as the default, I'll have it specified there. So that's it. Now I have this public function called set hash password. So I could at any point call this and it would do the encryption. And then I would have the right value for the hash password and I could save it to the database. So for example on new dot php, right here before I save it, I could just call admin and then set hash password, right? So I'll set it, and then I'm ready to save it.
And once I go to save it, it will then save that hash version because that's how we program the active record, right? All that work we did in the last chapter, it's automatically going to save that property for hash password to the database. It won't save the other one for password because it's not listed up here in our DV column, so it'll get ignored. So we could do it that way. However, I don't love this idea of having to remember to always do this. I would have to do it for creating a new one as well as for updating. I would rather if that could just happen automatically behind the scenes, and it can.
I'm going to cut that line out of there, let's go back over here, I'll close up my form fields. Let's go back over to the admin class. Now, we have in our database object class, if you remember, we wrote one here called create, right? We wrote another one here called update. What I really want is before those functions get called, to have the encryption happen automatically so that it hashes it and then it calls these methods. So we're inheriting those into our admin class.
So stop and think for a second, how can we perform an action and then have that action that's in the inherited behavior take place? We have the ability to do that. We can do it by overriding the original, create and I'll just do another one here, public function update, and I can override the behavior so that now it calls this set hash password, and then once it's done, it can call the parent version of create.
Remember this from the object oriented programming class? Where we talked about how we can call the parent object? So I'm saying do your own version of create, and then call the parent's version of create. And we also want to make sure that we have a return back after that because this is going to return a value, true or false, and we want to make sure we return that back from our overridden method as well. So this is just going to basically hash the password and then call the original version. We can do the same thing here, let's copy this and put it down here in update.
And it'll do the exact same thing. Now I actually made a small mistake here. If I go back to database class dot php, you'll see that these were protected functions, which means I do have access to them, but I need to keep the same visibility. Those need to be protected. I'll copy that. And because set hash password is now only being called internally to this class, it no longer needs to be public. I can actually make it protected as well. So now it's a protected function, these are protected functions. When I call save, it will automatically do this process for us.
Now that we're hashing the password, let's try it out. Let's come back over here, let's create a new admin. You can feel free to use your name. I'll do mine, Kevin Skoglund. Email, I'm going to just say Kevin at nowhere dot com. Username, for me it's going to be kskoglund, and password, and I'll just put in something like secretpassword. Not the best password, but it'll get us by for now. Now create admin, and look at that. It created the admin for us. Now we don't see the password there, we're not showing it anywhere, but we can go into our consul and log into mysql.
And let's take a look. Let's say select all from admins. And you should see an encrypted password here, right? Seeing this dollar sign in front, that lets you know that this is a blowfish or bcrypted password. And then we can exit back out of mysql. Now we have more work to do still, we actually aren't logging in the users or anything like that, so we've got more work ahead of us, but we now have the ability to hash passwords when we create admins in the database.
I think we were able to do it in a pretty slick way by using this call to the parent class.
Note: This is an intermediate-level training course that assumes you have existing knowledge of PHP. To refresh your skills, check out PHP Essential Training and PHP: Object-Oriented Programming.
- Creating a project database and tables
- Connecting to the database
- Database queries with OOP
- The active record design pattern
- Defining a database-driven class
- Performing common database tasks with OOP
- Creating inheritable and reusable code
- Object-oriented user authentication
- Object-oriented pagination