您当前的位置: 首页 >  .net

寒冰屋

暂无认证

  • 3浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

要求在ASP.NET Core 2.2中确认电子邮件——第2部分

寒冰屋 发布时间:2019-01-06 16:15:12 ,浏览量:3

目录

介绍

使用代码

先决条件

步骤1——将UnconfirmedEmail属性添加到IdentityUser

第2步——更新数据库

第3步——添加更改电子邮件页面

第4步——修改配置文件

第5步——重写UserManager

在新的ASP.NET Core 2.2 Razor页面模板中支持并修改Identity

  • 下载源代码 - 931.3 KB
介绍

ASP.NET Core 2.2 Web应用程序2部分中的第2部分,允许用户更新已确认的电子邮件。以下是允许用户更新其电子邮件的步骤。

要求在ASP.NET Core 2.2中确认电子邮件——第1部分

使用代码 先决条件
  • .NET Core 2.2 SDK
  • 以下VS中的一个:
    • Visual Studio版本2017年15.9或更高版本
    • Visual Studio for Mac 7.7或更高版本
    • Visual Studio Code C#扩展版本1.17.1或更高版本

您可以在完成第1部分中的步骤后下载VS 2017项目或按照以下步骤修改您自己的项目。

步骤1——将UnconfirmedEmail属性添加到IdentityUser

在Entities文件夹中添加命名为ApplicationUser的新类:

using Microsoft.AspNetCore.Identity;

namespace .Entities
{
    public class ApplicationUser : IdentityUser
    {
        [PersonalData]
        public string UnconfirmedEmail { get; set; }
    }
}

使用查找和替换,以当前工程中替换为。

使用ApplicationUser编辑Startup.cs > ConfigureServices:

services.AddIdentity

编辑Areas\Identity\Pages\Account\Manage\EnableAuthenticator.cshtml.cs:

private async Task LoadSharedKeyAndQrCodeUriAsync(ApplicationUser user)

编辑Areas\Identity\Pages\Account\Manage\DownloadPersonalData.cshtml.cs:

var personalDataProps = typeof(ApplicationUser).GetProperties().Where(
                        prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute)));

编辑Areas\Identity\Pages\Account\ExternalLogin.cshtml.cs:

var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email };

编辑Register.cshtml.cs:

var user = new ApplicationUser { UserName = Input.UserName, Email = Input.Email };

解决替换IdentityUser的命名空间问题。

using .Entities;

或者用于cshtml:

@using .Entities;

构建项目并检查错误。

第2步——更新数据库

编辑在Data文件夹中的ApplicationDbContext,添加ApplicationUser:

public class ApplicationDbContext : IdentityDbContext

从VS 2017中的程序包管理器控制台运行命令“ Add-Migration UnconfirmedEmail ”。

运行命令“ Update-Database”。

第3步——添加更改电子邮件页面

编辑ManageNavPages.cs,在上面添加ChangePassword属性:

public static string ChangeEmail => "ChangeEmail";

和:

public static string ChangeEmailNavClass(ViewContext viewContext) =>
                                         PageNavClass(viewContext, ChangeEmail);

编辑_ManageNav.cshtml,在下面添加个人资料项:

  • Email
  • 在Areas\Identity\Pages\Account\Manage中创建名为ChangeEmail的razer页面。

    编辑ChangeEmail.cshtml:

    @page
    @model ChangeEmailModel
    @{
        ViewData["Title"] = "Change Email";
        ViewData["ActivePage"] = ManageNavPages.ChangeEmail;
    }
    
    @ViewData["Title"]
    
    
    
    New email needs to be verified.
    Update Email
    @section Scripts { }

    编辑ChangeEmail.cshtml.cs:

    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Text.Encodings.Web;
    using System.Threading.Tasks;
    using .Services;
    using .Entities;
    
    namespace .Areas.Identity.Pages.Account.Manage
    {
        public class ChangeEmailModel : PageModel
        {
            private readonly UserManager _userManager;
            private readonly SignInManager _signInManager;
            private readonly ILogger _logger;
            private readonly IEmailSender _emailSender;
    
            public ChangeEmailModel(
                UserManager userManager,
                SignInManager signInManager,
                ILogger logger,
                IEmailSender emailSender)
            {
                _userManager = userManager;
                _signInManager = signInManager;
                _logger = logger;
                _emailSender = emailSender;
            }
    
            [BindProperty]
            public InputModel Input { get; set; }
    
            [TempData]
            [Display(Name = "Verified Email")]
            public string Email { get; set; }
    
            [TempData]
            public string StatusMessage { get; set; }
    
            public class InputModel
            {
                [Required]
                [EmailAddress]
                [Display(Name = "New Email")]
                public string Email { get; set; }
            }
    
            public async Task OnGetAsync()
            {
                var user = await _userManager.GetUserAsync(User);
                if (user == null)
                {
                    return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
                }
    
                var email = await _userManager.GetEmailAsync(user);
    
                Email = email;
    
                return Page();
            }
    
            public async Task OnPostAsync()
            {
                if (!ModelState.IsValid)
                {
                    return Page();
                }
    
                var user = await _userManager.GetUserAsync(User);
                if (user == null)
                {
                    return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
                }
    
                var email = await _userManager.GetEmailAsync(user);
                if (Input.Email != email)
                {
                    var errors = new List();
                    if (_userManager.Options.User.RequireUniqueEmail)
                    {
                        var owner = await _userManager.FindByEmailAsync(Input.Email);
                        if (owner != null && !string.Equals
                           (await _userManager.GetUserIdAsync(owner), 
                            await _userManager.GetUserIdAsync(user)))
                        {
                            ModelState.AddModelError(string.Empty, 
                            new IdentityErrorDescriber().DuplicateEmail(Input.Email).Description);
                            return Page();
                        }
                    }
    
                    var setEmailResult = await _userManager.SetEmailAsync(user, Input.Email);
                    if (!setEmailResult.Succeeded)
                    {
                        var userId = await _userManager.GetUserIdAsync(user);
                        throw new InvalidOperationException($"Unexpected error occurred 
                                           setting email for user with ID '{userId}'.");
                    }
    
                    if (Input.Email.ToUpper() != email.ToUpper())
                    {
                        var result = await _userManager.UpdateSecurityStampAsync(user);
                        if (!result.Succeeded)
                        {
                            foreach (var error in result.Errors)
                            {
                                ModelState.AddModelError(string.Empty, error.Description);
                                return Page();
                            }
                        }
    
                        var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
    
                        var callbackUrl = Url.Page(
                            "/Account/ConfirmEmail",
                            pageHandler: null,
                            values: new { userId = user.Id, code = code },
                            protocol: Request.Scheme);
    
                        await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                            $"Please confirm your account by 
                            clicking here.");
    
                        _logger.LogInformation("User updated their UnconfirmedEmail.");
                        StatusMessage = "Please check your inbox to confirm the new email.";
    
                    }
                    else
                    {
                        _logger.LogInformation("User updated their Email.");
                        StatusMessage = "Your email has been updated.";
                    }
                }
    
                return RedirectToPage();
            }
        }
    }
    第4步——修改配置文件

    在Areas\Identity\Pages\Account\Manage中编辑Index.cshtml.cs使用新的ChangeEmail页面。

    添加:

    public string Email { get; set; }

    去掉:

    public bool IsEmailConfirmed { get; set; }

    从InputModel中删除:

    [Required]
    [EmailAddress]
    public string Email { get; set; }

    从OnGetAsync>Input中删除:

    Email = email,

    从OnGetAsync中删除:

    IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);

    从OnPostAsync中删除:

    var email = await _userManager.GetEmailAsync(user);
    if (Input.Email != email)
    {
        var setEmailResult = await _userManager.SetEmailAsync(user, Input.Email);
        if (!setEmailResult.Succeeded)
        {
            var userId = await _userManager.GetUserIdAsync(user);
            throw new InvalidOperationException($"Unexpected error occurred
                         setting email for user with ID '{userId}'.");
         }
     }

    删除:

    public async Task OnPostSendVerificationEmailAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }
    
        var user = await _userManager.GetUserAsync(User);
        if (user == null)
        {
            return NotFound($"Unable to load user with ID '
            {_userManager.GetUserId(User)}'.");
        }
    
    
        var userId = await _userManager.GetUserIdAsync(user);
        var email = await _userManager.GetEmailAsync(user);
        var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
        var callbackUrl = Url.Page(
            "/Account/ConfirmEmail",
            pageHandler: null,
            values: new { userId = userId, code = code },
            protocol: Request.Scheme);
        await _emailSender.SendEmailAsync(
            email,
            "Confirm your email",
            $"Please confirm your account by clicking here.");
    
        StatusMessage = "Verification email sent. Please check your email.";
        return RedirectToPage();
    }

    编辑Index.cshtml。

    更换:

    @if (Model.IsEmailConfirmed)
    {
    
    } else { Send verification email }

    使用:

    第5步——重写UserManager

    在Services文件夹中添加命名为ApplicationUserManager的新类:

    using Microsoft.AspNetCore.Identity;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using .Entities;
    
    namespace .Services
    {
        public class ApplicationUserManager : UserManager
        {
            public ApplicationUserManager(IUserStore store,
                IOptions optionsAccessor,
                IPasswordHasher passwordHasher,
                IEnumerable userValidators,
                IEnumerable passwordValidators,
                ILookupNormalizer keyNormalizer,
                IdentityErrorDescriber errors,
                IServiceProvider services,
                ILogger logger)
                : base(store, optionsAccessor, passwordHasher, userValidators,
                      passwordValidators, keyNormalizer, errors, services, logger)
            {
            }
    
            /// 
            /// Sets the  address for a .
            /// 
            /// The user whose email should be set.
            /// The email to set.
            /// 
            /// The  that represents the asynchronous operation, 
            /// containing the 
            /// of the operation.
            /// 
            public override async Task SetEmailAsync(ApplicationUser user, string email)
            {
                ThrowIfDisposed();
                if (user == null)
                {
                    throw new ArgumentNullException(nameof(user));
                }
    
                if (user.EmailConfirmed && user.Email.ToUpper() != email.ToUpper())
                    user.UnconfirmedEmail = email;
                else
                    user.Email = email;
    
                return await UpdateUserAsync(user);
            }
    
            /// 
            /// Validates that an email confirmation token matches the specified 
            ///  and if successful sets
            /// EmailConfirmed to true and if UnconfirmedEmail is not NULL or Empty, 
            /// copies the user's UnconfirmedEmail to user's
            /// Email and sets UnconfirmedEmail to NULL.
            /// 
            /// The user to validate the token against.
            /// The email confirmation token to validate.
            /// 
            /// The  that represents the asynchronous operation, 
            /// containing the 
            /// of the operation.
            /// 
            public override async Task 
                      ConfirmEmailAsync(ApplicationUser user, string token)
            {
                ThrowIfDisposed();
                if (user == null)
                {
                    throw new ArgumentNullException(nameof(user));
                }
    
                IdentityResult result;
                var provider = Options.Tokens.EmailConfirmationTokenProvider;
                var isValidToken = await base.VerifyUserTokenAsync
                                   (user, provider, "EmailConfirmation", token);
    
                if (isValidToken)
                {
                    if (!string.IsNullOrEmpty(user.UnconfirmedEmail))
                    {
                        user.Email = user.UnconfirmedEmail;
                        user.UnconfirmedEmail = null;
                    }
                    user.EmailConfirmed = true;
                    result = await UpdateUserAsync(user);
                }
                else
                {
                    result = IdentityResult.Failed(new IdentityErrorDescriber().InvalidToken());
                }
    
                return result;
            }
        }
    }

    编辑Startup.cs > ConfigureServices,添加.AddUserManager():

    services.AddIdentity(config =>
        {
            config.SignIn.RequireConfirmedEmail = true;
            config.User.RequireUniqueEmail = true;
        })
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores()
        .AddUserManager()
        .AddDefaultTokenProviders();

    构建并测试项目。

     

    原文地址:https://www.codeproject.com/Articles/1272510/Require-Confirmed-Email-in-ASP-NET-Core-2-2-Part-2

    关注
    打赏
    1665926880
    查看更多评论
    立即登录/注册

    微信扫码登录

    0.1377s