Checking email in PHP

Currently users can create an account on my website (username, password, email)

This wil creates a database entry that stores the username, password hash and email and sets the user level to 0. It will then send an email with a URL that contains the user id and a new hash of the hashed password.

$emailhash = password_hash($passwordHash, PASSWORD_BCRYPT, $options);
$url = "domain/validation.php?id=$id&hash=$emailHash";

      

On the verification page that the URL points to, it uses the hashed password as the password and the hash from the email to check if the user is using an existing email address.

password_verify(hashedPasswordFromDB, hashOfHashFromEmail);

      

Is this a safe way to validate the user or should I add an extra table / column for an extra hash? And what are the pro / cons of my current method and / or another method? (like a simpler table ...)

EDIT : If the user wants to change their email address (something I'm adding at the moment), I want to implement the same method (sending a URL that contains an id, a new email and a new hash of the hashed password + new E-mail address). It looks a little tricky to me, but I don't see any other way to change it.

+3


source to share


3 answers


Since we got into this, I'm going to throw in my 2 cents to not just do it, but do it well.

Most people suggest adding a column or 2 to the user table. It's simple and it works.

But if you want to do it well, there are things you want to consider:

  • Will you also support password reset via email
  • You will get tired of checking or reset
  • Can you track someone trying to compromise your account?
  • Is there some kind of denial of service or other issue?

The best way to do this is to have a separate set of tables associated with the user table that capture these types of account events.

Here is a list of typical account events:

  • Registering an account
  • Account verification
  • Account verification
  • Deleting an account
  • Password reset request
  • Change email address

In a reliable system, each of these events, each with a time stamp, will often expire.



Many of them have an associated hash that needs to be saved and emailed.

They all have a completed flag to indicate whether the implied action has completed.

So the best way to deal with this is to have a separate linked table with the user. For discussion, this table would look something like this:

user_event
-----------
user_event_id (pk)
user_id (fk from user table)
created_on (timestamp)
event_type (registration | verification | password reset, etc)
expires_on (datetime) - manually set as is suitable
token (char40) - sha1
is_complete (tinyint)  A boolean to indicate if the action was completed
complete_on (timestamp)
user_ip (ip address of end user)
extra (varchar) : store the new email here.  Change to old email when you complete the request. 

      

It is a much more reliable way of storing the data required for these activities within the system, as well as some built-in logging. You have an audit trail of the activity and can handle or prevent retry requests.

You can also expire reset requests and use those expired requests to perform aging actions such as sending email reminders to people who never completed their registration.

You now have a system that supports additional account-related functionality without a separate separate table, and you can create new events by simply creating a new event_type. It can be a string, but you can also create a lookup table and use it as a foreign key in the user_event table.

+3


source


Better to create a separate token (some hash that is sent by the link as a request), which is stored with a timestamp in the database. This way you have the link and can be validated with a timestamp if the link has expired (compare the token's timestamp with the current request time (when the user opens their link).



+3


source


I would say: an extra hash or any random string in your database. No need to send password or even hashed password string by string.

+2


source







All Articles