Building a user registration system – Part 3: The Password Reset Form

So now we’ve come to the last part of this series. We need a way to let users back in when they forget their passwords. So we’re going to need a form, a mechanism to notify them with a unique token, as well as another form to actually do the resetting of the password. Plenty of going on here, so let’s start coding.

Update 9/5/2016: Updated flaw in token creation and token checking for better security. Thanks to comment by Mohammad and his findings.

Update 7/20/2016: Added index.php file to the views directory. This is the view that is being used once a successful login is processed.

View in Github

The Forgot your Password form

In our controller “Main.php”, let’s add a new action called “forgot”. The code is below and I’ll explain what is inside:

The action opens up the same way we have with our other forms. We have our validation rules for our “email” input field. In our form, all we’re really asking for our user is to enter their password. So we just need to run a couple of rules against this value: valid email and required. Once our validation passes, we also clean the data with our xss_clean() method which is loaded automatically. To learn more about the Security Helper click here.

Now we check if the email submitted exists in our database through our Model method: getUserInfoByEmail(). So add the code below to our Model (User_Model.php). This method returns the record on success and false on fail.

We also need another method that checks grabs the user information. This method called “getUserInfo()” simply returns the row and false if none is found:

So back in our “forgot” action, we simply set a couple of error messages when we receive a false from our model, or proceed with the token creation “insertToken()” on success. Note that we are reusing this method from our previous action when creating a new user.

The code for our view is below. Just some messaging our form and input fields. Notice we’re using CodeIgniter’s Form class.

forgot-password

Now go ahead and try out your form. Try an email that doesn’t exist – and try one that does. With our unique token code in our action, we continue to construct the link and “echo” to the browser. Remember that this is to be emailed to the user but we are simply echoing it out for demo purposes. The link should look like below:

token

The Reset Password Form

So now we have a unique link that we’ve sent to our forgetful user. Once they click on this link – they better have a page to land on, with a way to reset their password. So let’s build that now.

Let’s create another action in our controller, name it “reset_password()” and add the code below:

So our users will land in our page called “reset_password”, with a token in the url. First we need to process that and determine if its a good token. This is accomplished by our model’s isTokenValid() method. This method is the same method we had in our “complete” action when we are registering a new user – so this is nothing new. And if you remember, this method returns user information on success – so we go on with our setup for the form. We pass this information using $data array straight to our view, reset_password.php:

Clicking the link with the token will run our view. And if you did it correctly, it should render like below:

reset-password

Finally, we do some validation and sanitation on the passwords entered. Once passed, we continue to encrypt our user’s password through the create_hash() method. Remember this method is from our Password class that we’ve also used when creating new users. Then we update the user’s password on success.

Conclusion

So there you have our basic user registration system, explained in detail. Remember that this is mainly to get a grasp on what goes on behind the scenes of such a system as well as learning the ropes of MVC. It is also important to know that this is not production code. There are plenty of improvements to be made. But this should be enough to get you started.

38 Comments

      • Ohhh thank, but I worked on this some other way and both register and forgot works perfectly. Thank you very much for this tutorial and great code 🙂

  1. thanks a lot , it is working nicely , i am new to CI , and this tutorial helping me in learning this , but forget password is not working for me , ???
    any help ???

    Reply
    • You can stop the code by echoing out every step of the way. I would start when the page loads after the link is clicked. Simply echo out what is being processed.

      Reply
  2. Upon pressing Complete on the password/password confirm page, I get the error: “Unable to load the requested file: index.php”. Any idea what’s going wrong?

    Reply
  3. Fatal error: Call to undefined method User_model::getUserInfo() in C:\xampp\htdocs\xxxxxxxxx\application\models\user_model.php on line 68

    Reply
  4. Thanks for such a nice tutorial. I appreciate your efforts.

    Although you made a tiny mistake. Notice I was getting an error:
    Call to undefined method Auth_model::getUserInfo()

    I believe you forgot to mention getUserInfo() method in tutorial but its there in the github(https://github.com/michaelsoriano/user-registration-codeigniter) package.

    Anybody facing same issue can copy or create getUserInfo() method from User_model.php hosted at github (https://github.com/michaelsoriano/user-registration-codeigniter).

    Thank you.

    Reply
  5. I am getting an error..

    An uncaught Exception was encountered
    Type: Error
    Message: Call to undefined function redirect()
    Filename: /Users/xxxxxx/application/controllers/Main.php
    Line Number: 20

    Did you create a redirect function?

    Reply
  6. Thanks for the great code. It has been a major help!
    I have now added another view that only logged in users should be able to see. How would you recommend checking that a user is logged in before making a page visible? At the moment it’s possible just to type the name of the view in the url, and it will be displayed.

    Reply
    • you can create a function “isloggedin()” and add it to your controllers (maybe in the construct) – So it runs each time. So when you load your page, it should check it.

      Reply
  7. Amazing tutorial! Just one question. Is it possible to make the $url a route instead of using the controller and function name in the URL?

    Reply
  8. please send us even more pages like forgot_password.php registration page and login page with activation email

    Reply
  9. Hello, i used the exact same code and when I click on send email no email is send which is weird.
    Do you know what I could do to fix it?

    Reply
    • The code is only supposed to output the message in the browser. Assuming you don’t have mail service setup. You can take that message and send it via mail().

      Reply

Leave a Comment.