asp.net核心现有用户确认电子邮件,或允许更改电子邮件地址

时间:2018-09-18 13:28:14

标签: asp.net asp.net-mvc asp.net-core

我只是想知道如何处理以下情况。

我目前有一个ASP.NET MVC应用程序,正在将其转换为ASP.NET Core。 在旧的asp.net mvc应用程序中,我们从未收到过电子邮件确认。我打算强迫所有现有用户和新用户在新的asp.net核心版本中确认电子邮件。我相信我可以通过登录控制器来做到这一点。

问题
我面临的问题是,如果人们使用伪造的电子邮件地址或使用其他人的地址,那么他们将永远无法确认该电子邮件。

建议的解决方案
因此,我想到的一种处理方式是,当用户登录时,我可以给他们一个选项来更改其电子邮件并将确认发送到该新电子邮件地址吗?

那是明智的吗?有什么好的替代方法可以解决此问题?

1 个答案:

答案 0 :(得分:1)

我建议创建一个资源过滤器,以检查用户的电子邮件是否已确认,以及是否未重定向到用于处理该视图的视图:

public class EmailConfirmedResourceFilter : IAsyncResourceFilter
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly IUrlHelperFactory _urlHelperFactory;

    public EmailConfirmedResourceFilter(UserManager<ApplicationUser> userManager, IUrlHelperFactory urlHelperFactory)
    {
        _userManager = userManager ?? throw new ArgumentNullException(nameof(userManager));
        _urlHelperFactory = urlHelperFactory ?? throw new ArgumentNullException(nameof(urlHelperFactory));
    }

    public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
    {
        var urlHelper = _urlHelperFactory.GetUrlHelper(context);
        var ignoreUrls = new[]
        {
            urlHelper.RouteUrl("ConfirmEmail"),
            urlHelper.RouteUrl("ChangeEmail")
        };
        if (!ignoreUrls.Contains(context.HttpContext.Request.Path.ToString())
            && context.HttpContext.User.Identity.IsAuthenticated)
        {
            var user = await _userManager.GetUserAsync(context.HttpContext.User);
            if (user != null && !await _userManager.IsEmailConfirmedAsync(user))
            {
                context.Result = new RedirectToRouteResult("ConfirmEmail");
            }
        }

        await next();
    }
}

然后,在Startup.cs中:

services.AddMvc(o => {
    o.Filters.Add<EmailConfirmedResourceFilter>();
});

services.AddScoped<EmailConfirmedResourceFilter>();

这似乎是很多代码,但是非常简单。首先,过滤器调出一些应忽略的URL。如果我们在这些页面之一上,我们就不想再次重定向,尤其是因为这有可能导致无限重定向循环。我们还会检查用户是否已通过身份验证,因为如果他们甚至没有登录,这都是有争议的。

假设这些测试通过,然后我们拔出用户并检查是否确认了他们的电子邮件。如果没有,我们将重定向到他们可以执行此操作的地方。否则,所有内容都会落入await next();行,该行仅将控制权传递给管道中的下一件事(即,我们什么也不做,让请求处理继续进行)。

如果用户尚未确认,这将迫使用户在尝试导航到其他任何地方时强制其进入电子邮件确认页面。在上述页面上,您可以选择更改电子邮件地址(这本身需要确认)或发送电子邮件以简单地确认现有电子邮件地址。一旦用户确认了任何一种方式,他们将绕过此检查,并且可以继续前进到要在网站上进行其他操作的地方。