I am designing a REST API that allows users to register and authenticate with an email address and a password. Before being able to authenticate, I want to ensure that the user owns the email address they are using, so I send them a verification email with a token. My issue is that the token can expire, so I need a way to resend the verification email, and this is where I'm having problems.
Basic Setup
I have two models: EmailAddress
and EmailConfirmation
. EmailAddress
stores the address, the user who owns it, and a boolean indicating if it's verified. EmailConfirmation
contains a key used to verify a specific email address.
Approach 1
When a user registers, I create a new user and an EmailAddress
instance owned by that user. A confirmation is sent to the email. If the confirmation is expired, the user can request a new confirmation.
The issue with this approach is multiple users can sign up with the same email address until someone verifies that address. If there are multiple EmailAddress
instances with the same address, how do I determine which of them requested the verification to be resent?
Approach 2
When a user registers, we create an EmailAddress
instance for the address, but don't assign a user to it. If additional users register with the same address, we don't create new instances. Instead, the EmailConfirmation
model has an attached user and we set ownership of the address based on which key is used to verify it.
The issue with this approach is how to determine which user requested a new confirmation email.
Further Notes
- User's shouldn't be able to prevent others from taking an email address. For example: If Fred registers with
[email protected]
but can't verify it, Bob should still be able to register with[email protected]
and verify it.
I am happy to take a different approach than the ones described above, but those are the only ones I can think of. Any help would be greatly appreciated.
Edit: I believe the original title of my question was a little misleading. I'm more interested in solving the issues with resending a confirmation email. However, if this involves restructuring my approach to the whole system I'm happy to do that.
Edit 2: To further clarify my question, I'm talking about the case where a user registers and gets sent a verification email. For whatever reason, they don't use the token they've received in time and it expires, or they simply lose the email. They then request a new confirmation email be sent by submitting their email address.
I believe the problem boils down to determining which user requested a new email confirmation without any knowledge of the initial verification token.