Email Confirmation is quite an important part of the user registration process. It allows us to verify the registered user is indeed an owner of the provided email. But why is this important?

Well, let’s imagine a scenario where two users with similar email addresses want to register in our application. Michael registers first with [email protected] instead of [email protected] which is his real address. Without an email confirmation, this registration will execute successfully. Now, Michel comes to the registration page and tries to register with his email [email protected]. Our application will return an error that the user with that email is already registered. So, thinking that he already has an account, he just resets the password and successfully logs in to the application.

We can see where this could lead, and what problems it could cause.

To download the source code for this project, visit the Email Confirmation with ASP.NET Core Identity repository.

To navigate through the entire series, visit the ASP.NET Core Identity series page.

Let’s look at the basic navigation for this article:

Enabling Email Confirmation in a Project

To enable Email Confirmation in ASP.NET Core Identity, we have to modify the configuration part:

We use the SignIn property from the IdentityOptions class and then initialize the RequireConfirmedEmail to true. By doing that, we specify that SigninManager cheks if the email is confirmed before successfully signing in the user.

If we check our database, we are going to see that our user doesn’t have confirmed email address:

Email confirmation not confirmed

Now, let’s see what’s going to happen when this user tries to log in:

Log in withour email confirmation

As we can see, we get the Invalid UserName or Password error message, even though we provide valid credentials. But this is just because we haven’t modified the Login logic to support the email confirmation functionality. If we inspect the console log though, we are going to see the real reason for the login failure:

console log email confirmation

Of course, our users won’t look at the console to understand what went wrong, so we have to adjust the Login action.

Modifying the Login Action to Support Email Confirmation

As we said, we don’t want to see an „Invalid Username or Password“ message if an email is not confirmed. We can change that message to something generic like „Invalid Login Attempt“:

Additionally, if we explicitly want to notify our user about email confirmation error, we can use the helper method from UserManager:

await _userManager.IsEmailConfirmedAsync(User user)

Now, if we test the Login functionality again, we are going to see a new message on the form.

Implementing Email Confirmation in the Registration Process

To Implement Email Confirmation in our project, we have to modify the POST Register action and to add an additional action as well.

So, let’s start with the modification first:

As with the ForgotPassword action, we create a token but with a different helper method: GenerateEmailConfirmationTokenAsync(TUser). Then, we create a confirmation link and send a message to the user. Of course, we have to create two additional actions that we call in this action: ConfirEmail and SuccessRegistration.

Additional Actions and Views

First, let’s create these actions:

And views as well:

Now, all we have to do is to implement the ConfirmEmail action:

Well, we check if the user exists in the database by email. If it’s not, we return an error view. Otherwise, we use the ConfirmEmailAsync method to confirm received email and depending on the result, return either ConfirmEmail or Error view.

So, let’s just add the Error action and create the Error view:

With all that in place, we are ready for the test. We are going to delete an existing user from the database and create the same one again:

Email verification complete

Let’s check our database to see what we did:

Email confirmed db

Excellent.

But still not completed.

Modifying Lifespan of the Email Token

Now, if we check the ConfigureServices method, we are going to see that this token will last for two hours as well as the reset password token. That’s because the reset and confirmation functionality all use the same data protection token provider with the same instance of the DataProtectionTokenProviderOptions class.

But, we don’t want our email token to last two hours – usually, it should last longer. For the reset password functionality, a short period of time is quite ok, but for the email confirmation, it is not. A user could easily get distracted and come back to confirm its email after one day for example. Thus, we have to increase a lifespan for this type of token.

To do that, we have to create a custom token provider.

Let’s create the CustomTokenProviders folder with the EmailConfirmationTokenProvider class:

And that’s all we have to do. Create a class that implements DataProtectionTokenProvider and override its constructor with the custom token provider options class.

Now, we can modify the ConfigureServices method:

So, in the AddIdentity method, we state that we want our EmailConfirmationTokenProvider to use the provider with the name „emailconfirmation“. Then, we register our custom token provider with the AddTokenProvider<T> method, and finally, configure its life span to three days.

And we’ve finished our job.

Conclusion

We did a great job here. We have covered all the things we require for the successful email confirmation.

In the next article, we are going to learn how to implement lockout functionality in our project.

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published .NET Core content we encourage you to subscribe to our blog.