1

I want to implement email confirmation with digit code for my .net core web app. I make use of the GenerateEmailConfirmationTokenAsync from the UserManager class, but it returns a token instead of a digit code. I think I should create a custom implementation using the IUserTokenProvider interface, but I cant find any example.

How can I implement this using the IUserTokenProvider?

Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
Dev123
  • 53
  • 1
  • 9

2 Answers2

2

You use that token to generate a action callback url

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
            var callbackUrl = Url.Action(
               "ConfirmEmail", "Account", 
               new { userId = user.Id, code = code }, 
               protocol: Request.Url.Scheme);

            await UserManager.SendEmailAsync(user.Id, 
               "Confirm your account", 
               "Please confirm your account by clicking this link: <a href=\"" 
                                               + callbackUrl + "\">link</a>");
            // ViewBag.Link = callbackUrl;   // Used only for initial demo.
            return View("DisplayEmail");
        }
        AddErrors(result);
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

https://learn.microsoft.com/en-us/aspnet/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity

Anders
  • 17,306
  • 10
  • 76
  • 144
1

There is an existing implementation in ASP.NET Core Identity that does that.

The TotpSecurityStampBasedTokenProvider class (implementation of IUserTwoFactorTokenProvider interface) generates 6-digit tokens that expire.

TotpSecurityStampBasedTokenProvider is further inherited by EmailTokenProvider, but GenerateAsync method is reused from TotpSecurityStampBasedTokenProvider (not overridden).

These classes use user's security stamp to generate tokens, and provide their own modifiers, but the actual token generation is done by GenerateCode method from Rfc6238AuthenticationService class.

So, you can use the existing implementations:

  • TotpSecurityStampBasedTokenProvider
  • EmailTokenProvider (it does the same as the above one)
  • Rfc6238AuthenticationService if you really want to customize the token
Marko Papic
  • 1,846
  • 10
  • 23
  • How can you make it return 4 digits? I've been trying to figure it out. I inherited from PhoneNumberTokenProvider<> and have overridden the GenerateAsync, but if you get the code from the base.GenerateAsync call you can't manipulate it because it is already stored. Where is the code stored? In memory? Should I just roll my own storage in the GenerateAsync and ValidateAsync methods? – jmichas Jan 31 '20 at 13:46
  • As per usual, I post then come up with an answer on my own. I posted a gist of how I solved the problem of 4 digit token/codes. This could also be used to change the time window for validity to work with other services/use cases. https://gist.github.com/jmichas/dab35d9b8e916eae8936322465d76b66 – jmichas Jan 31 '20 at 15:50