Search code examples
c#asp.net-mvcemail

Email Confirmation Asp.net MVC


I have seen a lot of Examples where a users Confirmed registration is done through using a token generated through WebSecurity that is linked to simple membership but in order to take control of my own code I have wrote a lot of the user registration and logins from scratch using entity framework for DB access rather than trying to fight against tedious auto generated templates that give me no breakdown as to what is going on and that give me no confidence as to what is going on. I have to be honest that is how I feel about them as they don't show any code as to how the user db interacts with any of the custom functions I write.

So my query is has anyone used a custom token for email validation that does not have to use the websecurity.CreateAccount Method before?

I would have to do some amount of refactoring for already perfectly sound and functional code that it would be a shame. Many thanks in advance


Solution

  • Has anyone used a custom token for email validation that does not have to use the websecurity.CreateAccount Method before?

    Absolutely - we do this for all of our email verification tokens, which is part of our "CreateAccount" process. You could do something like this to generate the tokens :

    public static string GenerateEmailToken()
    {
        // generate an email verification token for the user
        using (RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider())
        {
            byte[] data = new byte[16];
            provider.GetBytes(data);
            return Convert.ToBase64String(data);
        }
    }
    

    I then include that in our "CreateAccountResponse", which allows the controller to pick it up and send the verification email with the token included - to give you an idea:

    public class CreateAccountResponse
    {
        public bool CreatedSuccessfully { get; set; }
    
        public string EmailVerificationToken { get; set; }
    }
    

    And then we handle that here:

    CreateAccountResponse response = _mediator.Send(createAccountCommand);
    
    if (response.CreatedSuccessfully)
    {   
        if (!string.IsNullOrEmpty(response.EmailVerificationToken))
        {
            // Send the verification email if a token is present
            SendVerificationEmail(model.Email, response.EmailVerificationToken);
        }       
    
        return RedirectToAction("Settings", "Account");
    }
    

    Then using the token, we create the fully formatted URL to include in the email you send to this user

    private void SendVerificationEmail(string emailAddress, string token)
    {
        try
        {
            // Url.Action will encode parameters as they are needed.
            var verificationUrl = Url.Action("VerifyAccount", "Account", new { token = token }, Request.Url.Scheme);
            _userMailer.DeliverVerification(emailAddress, verificationUrl);
        }
        catch (Exception ex)
        {
            _logger.ErrorLog.Log(new VerificationError(ex));
        }
    }
    

    Once they click the link in the email, our "VerifyAccount" route picks up the token and allows us to complete the rest of the verification process.

    Also, it's a very good idea to set an expiration for your verification tokens for security purposes - 24 to 48 hours is usually an acceptable time frame to allow the user to receive the email, click the link, and verify their account.