When someone has lost a password, they click on the lost or forgotten password link. They will need to enter their email address, then answer their own secret question if the secret question is correct, an email will be sent to them with a link that expires after 24hrs.
As the email is sent, a record is entered in a database table holding this information: - the email of the person who needs to reset the password - the hour which the resetting of the password will expire - the hour which the request to rest the password was submitted.
The sent link will lead the user to a form that allows them to enter their new password. In this form they will need to enter their email address and their password X2.
When they click on submit, a check is made against db to ensure that the email is valid (one that the password is being reset) and has not yet expired (by comparing the two dates to see if the expiry time has passed, which is 24 hrs)
If the email is valid, and has not yet expired, and the two passwords match & meet the minimum req, then the new password is applied.
A confirmation message is given on success.
Q1. Is this a good model for password recovery? Q2. How can I make sure that the link that is sent to the user's address is unique? In that no one will get the same link? So that nobody could just go to the password reset page and try different emails, rather have each account that needs to be reset have their own unique URL that work for that account only.
Regarding Q2:
I was thinking that when the user requests to have their password reset, a random unique id is generated and stored in the same record that expires after 24hrs. This random unique id's column could be called "rid"
The link in the email that will be sent to the user will end with ?rid=xxxxxxxxxxxxx
When the user clicks on submit in the page that resets the password, the "rid" at the top of the page is used to get the corresponding email address from the db, to compare it with the email address in the form. Doing this can ensure that each password reset case will have its own unique URL that no other account can use to reset its password.
Is this a viable solution?
Any contributions or suggestions will be appreciated.