ConfirmEmailAsync()方法无效

时间:2015-12-30 18:16:05

标签: email asp.net-identity-2 confirm

我在确认新用户电子邮件时遇到问题。确认电子邮件链接在前20分钟有效,但50分钟后链接将过期。我已将令牌过期时间设置为24小时。请帮我解决这个问题。我被困在最后2天:(。我的代码如下: 我在ApplicationUserManager中的Create()方法中设置令牌生存期,如下所示:

       var dataProtectionProvider = options.DataProtectionProvider;

        if (dataProtectionProvider != null)
        {
            userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"))
            {
                TokenLifespan = _settings.ConfirmationAndResetTokenExpirationTimeSpan
            };
        }

然后在AccountsController中,新用户的Create方法在下面是geiven。 SendEmailAsync方法包括电子邮件主题,电子邮件正文,生成的密码和回调uri。

[Authorize(Roles = Roles.Bam.Name.Admin)]
    [HttpPost]
    [Route(Routes.Accounts.Template.Create, Name = Routes.Accounts.Name.Create)]
    public async Task<IHttpActionResult> Create(CreateUserBindingModel createUserBindingModel)
    {
        IHttpActionResult result;


            var memberNameExists = UserManager.Users.Any(x => x.MemberName.ToLower() == createUserBindingModel.MemberName.ToLower());

            if (!memberNameExists)
            {
                var applicationUser = new ApplicationUser
                {
                    UserName = createUserBindingModel.Email,
                    Email = createUserBindingModel.Email,
                    FirstName = createUserBindingModel.FirstName,
                    LastName = createUserBindingModel.LastName,
                    Company = createUserBindingModel.Company,
                    Location = createUserBindingModel.Location,
                    PhoneNumber = createUserBindingModel.PhoneNumber,
                    MemberName = createUserBindingModel.MemberName,
                    LastLoginDate = SqlDateTime.MinValue.Value,
                    CreateDate = DateTime.Now,
                    CreatedBy = User.Identity.GetUserId(),
                    UpdateDate = DateTime.Now,
                    UpdatedBy = User.Identity.GetUserId(),
                    TwoFactorEnabled = createUserBindingModel.TwoFactorEnabled,
                    SecurityResetRequired = true,
                    PasswordExpirationDate = DateTime.Now.AddDays(Convert.ToDouble(ConfigurationManager.AppSettings["PasswordExpirationDays"]))
                };

                if (!string.IsNullOrEmpty(createUserBindingModel.AvatarBase64))
                {
                    var avatarBytes = Convert.FromBase64String(createUserBindingModel.AvatarBase64);
                    var resizedAvatarBytes = ImageResizer.ResizeImage(avatarBytes, _avatarWidth, _avatarHeight);

                    applicationUser.UserAvatar = new ApplicationUserAvatar
                    {
                        Avatar = resizedAvatarBytes
                    };
                }

                var generatedPassword = PasswordGenerator.GenerateStrongPassword(10, 10);

                var identityResult = await UserManager.CreateAsync(applicationUser, generatedPassword);

                if (identityResult.Succeeded)
                {
                    await UserManager.AddToRolesAsync(applicationUser.Id, createUserBindingModel.Roles.ToArray());

                    var token = await UserManager.GenerateEmailConfirmationTokenAsync(applicationUser.Id);
                    var callbackUri = string.Format("{0}?userId={1}&token={2}", createUserBindingModel.EmailConfirmationCallbackUri, applicationUser.Id, HttpUtility.UrlEncode(token));

                    await UserManager.SendEmailAsync(applicationUser.Id, Email.Confirmation.Subject, string.Format(Email.Confirmation.Body, string.Format("{0} {1}", applicationUser.FirstName, applicationUser.LastName), callbackUri, generatedPassword, _settings.AccessTokenExpirationTimeSpan.TotalHours));

                    var userUrl = new Uri(Url.Link(Routes.Accounts.Name.Get, new { id = applicationUser.Id }));
                    var roles = await UserManager.GetRolesAsync(applicationUser.Id);
                    var contract = _accountsMapper.ToContract(applicationUser, roles);

                    result = Created(userUrl, contract);
                }
                else
                {
                   result = GetErrorResult(identityResult);
                }
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Member Name already exists!");

                result = BadRequest(ModelState);
            }
        return result;
    }

生成电子邮件后,UI会跟随JS角度代码执行并提供用户ID和令牌服务。 Angular JS代码:

angular.module('confirmEmailModule').factory('confirmEmailFactory', function ($http) {
var factory = {};

factory.confirmEmail = function(userId, token) {

    var encodedToken = encodeURIComponent(token);
    var uri = '/identity/api/accounts/confirmemail?userId=' + userId + '&token=' + token;

    return $http.post(uri);
}

return factory;

});

,服务是:

[AllowAnonymous]
    [HttpPost]
    [Route(Routes.Accounts.Template.ConfirmEmail, Name = Routes.Accounts.Name.ConfirmEmail)]
    public async Task<IHttpActionResult> ConfirmEmail([FromUri] string userId, [FromUri] string token)
    {
        //var decodedToken = HttpUtility.UrlDecode(token);
        var identityResult = await UserManager.ConfirmEmailAsync(userId, token);
        var result = identityResult.Succeeded ? StatusCode(HttpStatusCode.NoContent) : GetErrorResult(identityResult);

        return result;
    }

请建议。

2 个答案:

答案 0 :(得分:1)

我找到了解决这个问题的方法。如果有人遇到同样的问题,我会张贴它。就我而言,服务和Web API位于不同的服务器上。不同的机器密钥导致此问题。所以我为我的Web应用程序生成了机器密钥,并在Identity服务的web.config文件中发布了相同的机器密钥。之后它起作用了。有关生成计算机密钥的更多信息,以下链接很有帮助。 http://gunaatita.com/Blog/How-to-Generate-Machine-Key-using-IIS/1058

答案 1 :(得分:1)

这对我有用。希望能对您有所帮助;

public async Task<IActionResult> ConfirmEmail(string userId, string token)
{
    if (userId == null || token == null)
    {
        return RedirectToAction("employees", "home");
    }

    var user = await userManager.FindByIdAsync(userId);
    if (user == null)
    {
        ViewBag.ErrorMessage = $"The User ID {userId} is invalid";
        return View("NotFound");
    }

    var result = await userManager.ConfirmEmailAsync(user, Uri.EscapeDataString(token));
    if (result != null)
    {
        user.EmailConfirmed = true;
        await userManager.UpdateAsync(user);
        return View();
    }
}