I am trying to ConfirmEmail but each time I get a Invalid token! I am calling the API from a angulaJS app http://www.codeproject.com/Articles/784106/AngularJS-Token-Authentication-using-ASP-NET-Web-A
// GET: /Account/ConfirmEmail
[System.Web.Http.HttpGet]
[System.Web.Http.AllowAnonymous]
[System.Web.Http.Route("ConfirmEmail")]
public async Task<IHttpActionResult> ConfirmEmail(string userId, string code)
{
var newcode = HttpContext.Current.Server.UrlDecode(code);
if (userId == null || code == null)
{
return BadRequest(ModelState);
}
var result = await UserManager.ConfirmEmailAsync(userId, newcode);
if (result.Succeeded) {
return Ok(result.Succeeded);
}
return GetErrorResult(result);
}
I ask for a Token in 2 places
1 in Account/Register var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
// await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Confirm your account");
return Ok(result.Succeeded);
}
return GetErrorResult(result);
}
and the other in ResendEmail.
[System.Web.Http.HttpGet]
[System.Web.Http.Route("ResendEmail")]
public async Task<IHttpActionResult> ResendEmail(string email)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByNameAsync(ActiveMember.Email);
if (user.Email == email)
{
var callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Confirm your Email");
}
return Ok();
}
// If we got this far, something failed, redisplay form
return BadRequest(ModelState);
}
SendEmailConfirmationTokenAsync Helper
private async Task<string> SendEmailConfirmationTokenAsync(string userId, string subject)
{
string host = Request.RequestUri.Host.ToLower();
string code = await UserManager.GenerateEmailConfirmationTokenAsync(userId);
string callbackUrl = host + "/#/account/ConfirmEmail?userId=" + userId + "&code=" + HttpContext.Current.Server.UrlEncode(code);
await UserManager.SendEmailAsync(userId, subject, "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a><p>" + userId + "<p>" + code + "<p>" + callbackUrl);
return callbackUrl;
}
And the IdentityCinfig just has
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<Member>(dataProtectionProvider.Create("Identity"));
// manager.UserTokenProvider = new EmailTokenProvider<Member, string>();
}
Is this something that I going wrong?
Thanks for your help.
I needed to encode the url and HttpUtilitu.UrlEncode wasn't effective, it replaced the character + with space which caused the token to be invalid.
I have two helper methods
public static string Base64ForUrlEncode(string str)
{
var encbuff = Encoding.UTF8.GetBytes(str);
return HttpServerUtility.UrlTokenEncode(encbuff);
}
public static string Base64ForUrlDecode(string str)
{
var decbuff = HttpServerUtility.UrlTokenDecode(str);
return decbuff != null ? Encoding.UTF8.GetString(decbuff) : null;
}
Register action
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = string.Format("{0}/#confirm-email?userId={1}&code={2}", "your-web-url", user.Id.ToString(), StringHelper.Base64ForUrlEncode(code));
and the ConfirmEmail action
var result = await UserManager.ConfirmEmailAsync(userId.ConvertToGuid(), StringHelper.Base64ForUrlDecode(code));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With