简体   繁体   中英

How can I securely provide a user with a new password in a PHP/MySQL web application?

I have a simple question. What is the best way to do a password recovery for a user?

I want the user to be able to click a link like "forget your password?" When clicked, the user will receive an email with a new password.

I think sending the hash is a bad option, then I must generate a random password, convert to a hash + random salt, replace it in the database and send the new random password by email. Is this the best way, or is there another? Simpler is better.

Thanks!

The safest way is to email the person a link to a page that allows them to create a new password. Passwords should only ever be stored as salted hashes. Subverting this process would require that a person's email be compromised -- in which case they've probably got worse problems than a compromised password to your webapp.


Files and tables:

I imagine that your database contains a table called "users", with a column called "userid" which serves as its primary key.

  1. Create a new table in your tabase called password_reset with three columns: userid , which is a foreign key pointing to the table users ; code , which will contain a unique, random number; and timestamp , which will contain the date that a request is made.

  2. Create a page for password resets, like password_reset_request.php . Ask for a username or email.

  3. Create a page for setting a new password, like set_new_password.php .

Logic:

  1. If the username or email supplied to password_reset_request.php is valid, insert a row in the password_reset table corresponding to the request. Imagine that user Fel has placed a password reset request. Fel 's internal userid might be 564979 . The row in password_reset would be something along these lines: 564979, 54c4a2767c2f485185ab72cdcf03ab59, 2011-01-01 12:00:00 .

  2. Send an email to the user's email address containing an url looking like this: http://your.url/set_new_password.php?userid=564979&code=54c4a2767c2f485185ab72cdcf03ab59 .

  3. When set_new_password.php gets a hit, it should check for the presence of the userid and code properties in the URL. Not there? Abort.

  4. Sanitize the userid and code properties if they're there. This is important.

  5. Run an SQL command like this: SELECT * FROM password_reset pr WHERE pr.userid = $userid AND pr.code = $code AND TIMESTAMPDIFF(DAY, CURTIME(), pr.timestamp) < 1 .

  6. If you receive no results, Abort.

  7. If you receive a result, allow the user to enter a new password.

  8. After validating the password as you normally would upon registration, use an SQL UPDATE statement to change the user's password.

  9. Use SQL to delete any requests for the user from the password_reset table: DELETE * FROM password_reset WHERE userid = $userid .

You're done!

I would do the following

  1. User requests password reset
  2. User enters either username or password
  3. An e-mail is sent to the user with a link with a unique hash that is placed in a database table (eg pwrecovery) - this link would be like: http://domain.com/pwrecover.php?key=KEYHERE
  4. The user clicks that link, if the hash exists in the table then they get sent another e-mail with their new password.

That way, users wont find their password being changed by random users when they get a correct e-mail.

You should email a link to a page with a security question (and a unique code to prevent people from getting other people's security questions).

After answering the question, allow the user to create a new password.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM