以使用者註冊、電子郵件確認和密碼重設建立安全的 ASP.NET Web Forms 應用程式 (C#)

作者 :Erik Reitan

本教學課程說明如何使用 ASP.NET 身分識別成員資格系統,建置具有使用者註冊、電子郵件確認和密碼重設的 ASP.NET Web Forms應用程式。 本教學課程是以 Rick Anderson 的 MVC 教學課程為基礎。

簡介

本教學課程會引導您使用 Visual Studio 建立 ASP.NET Web Forms應用程式,並 ASP.NET 4.5 建立具有使用者註冊、電子郵件確認和密碼重設的安全Web Form應用程式。

教學課程工作和資訊:

建立 ASP.NET Web Forms應用程式

注意

警告:您必須安裝Visual Studio 2013 Update 3或更高版本,才能完成本教學課程。

  1. 建立新的專案 (檔案- >新增專案) ,然後從 [新增專案] 對話方塊中選取[ASP.NET Web 應用程式] 範本和最新的.NET Framework版本。

  2. 從 [新增 ASP.NET 專案] 對話方塊中,選取Web Form範本。 將預設驗證保留為 個別使用者帳戶。 如果您想要在 Azure 中裝載應用程式,請保留 [ 雲端中的主機 ] 核取方塊。
    然後按一下 [ 確定 ] 以建立新的專案。
    [新增 ASP.NET 專案] 對話方塊

  3. 為專案啟用安全通訊端層 (SSL) 。 請遵循使用 Web Form 教學課程系列之 消費者入門啟用PROJECT 的 SSL一節中可用的步驟。

  4. 執行應用程式,按一下 [註冊] 連結並註冊新的使用者。 此時,電子郵件的唯一驗證是以 [EmailAddress] 屬性為基礎,以確保電子郵件地址格式正確。 您將修改程式碼以新增電子郵件確認。 關閉瀏覽器視窗。

  5. 在 Visual Studio 的[伺服器總管] ([檢視] - >[伺服器總管]) 中,流覽至[資料連線\DefaultConnection\Tables\AspNetUsers],以滑鼠右鍵按一下並選取 [開啟資料表定義]。

    下圖顯示 AspNetUsers 資料表架構:

    AspNetUsers 資料表架構

  6. [伺服器總管] 中,以滑鼠右鍵按一下 [AspNetUsers] 資料表,然後選取 [ 顯示資料表資料]。

    AspNetUsers 資料表資料
    此時尚未確認已註冊使用者的電子郵件。

  7. 按一下資料列,然後選取 [刪除] 以刪除使用者。 您將在下一個步驟中再次新增此電子郵件,並將確認訊息傳送至電子郵件地址。

Email確認

最佳做法是在註冊新使用者期間確認電子郵件,以確認他們不會模擬其他人 (也就是說,他們尚未向其他人的電子郵件註冊) 。 假設您有一個討論論壇,您會想要防止 "bob@cpandl.com" 註冊為 "joe@contoso.com" 。 如果沒有電子郵件確認, "joe@contoso.com" 可能會從您的應用程式收到不必要的電子郵件。 假設 Bob 不小心註冊為 "bib@cpandl.com" 且未注意到,他無法使用密碼復原,因為應用程式沒有正確的電子郵件。 Email確認僅提供來自 Bot 的有限保護,且不會提供來自判定垃圾郵件者的保護。

您通常想要防止新使用者在電子郵件、簡訊或其他機制確認之前,將任何資料張貼到您的網站。 在下列各節中,我們將啟用電子郵件確認並修改程式碼,以防止新註冊的使用者登入,直到確認電子郵件為止。 您將在本教學課程中使用電子郵件服務 SendGrid。

連結 SendGrid

SendGrid 已在撰寫本教學課程之後變更其 API。 如需目前的 SendGrid 指示,請參閱 SendGrid啟用帳戶確認和密碼復原

雖然本教學課程只會示範如何透過 SendGrid新增電子郵件通知,但您可以使用 SMTP 和其他機制傳送電子郵件 (請參閱 其他資源) 。

  1. 在 Visual Studio 中,開啟套件管理員主控台 (Tools - >NuGet Package Manger - >Package Manager Console) ,然後輸入下列命令:
    Install-Package SendGrid

  2. 移至 Azure SendGrid 註冊頁面 並註冊免費的 SendGrid 帳戶。 您也可以直接在 SendGrid 的網站上註冊免費的 SendGrid帳戶。

  3. 方案總管開啟App_Start資料夾中的IdentityConfig.cs檔案,並將下列以黃色醒目提示的程式碼新增至 類別, EmailService 以設定SendGrid

    public class EmailService : IIdentityMessageService
    {
       public async Task SendAsync(IdentityMessage message)
       {
         await configSendGridasync(message);
       }
    
       // Use NuGet to install SendGrid (Basic C# client lib) 
       private async Task configSendGridasync(IdentityMessage message)
       {
          var myMessage = new SendGridMessage();
          myMessage.AddTo(message.Destination);
          myMessage.From = new System.Net.Mail.MailAddress(
                              "Royce@contoso.com", "Royce Sellars (Contoso Admin)");
          myMessage.Subject = message.Subject;
          myMessage.Text = message.Body;
          myMessage.Html = message.Body;
    
          var credentials = new NetworkCredential(
                     ConfigurationManager.AppSettings["emailServiceUserName"],
                     ConfigurationManager.AppSettings["emailServicePassword"]
                     );
    
          // Create a Web transport for sending email.
          var transportWeb = new Web(credentials);
    
          // Send the email.
          if (transportWeb != null)
          {
             await transportWeb.DeliverAsync(myMessage);
          }
          else
          {
             Trace.TraceError("Failed to create Web transport.");
             await Task.FromResult(0);
          }
       }
    }
    
  4. 此外,將下列 using 語句新增至 IdentityConfig.cs 檔案的開頭:

    using SendGrid;
    using System.Net;
    using System.Configuration;
    using System.Diagnostics;
    
  5. 若要讓此範例保持簡單,您會將電子郵件服務帳戶值儲存在 appSettingsweb.config 檔案的 區段中。 將黃色反白顯示的下列 XML 新增至專案根目錄的 web.config 檔案:

    </connectionStrings>
       <appSettings>
          <add key="emailServiceUserName" value="[EmailServiceAccountUserName]" />
          <add key="emailServicePassword" value="[EmailServiceAccountPassword]" />
       </appSettings>
      <system.web>
    

    警告

    安全性 - 永不將敏感性資料儲存在原始程式碼中。 在此範例中,帳戶和認證會儲存在Web.config檔案的appSetting區段中。 在 Azure 上,您可以在Azure 入口網站的 [設定] 索引標籤上安全地儲存這些值。 如需相關資訊,請參閱 Rick Anderson 的主題,標題為將 密碼和其他敏感性資料部署至 ASP.NET 和 Azure 的最佳做法

  6. 新增電子郵件服務值,以反映您的 SendGrid 驗證值 (使用者名稱和密碼) ,以便您成功從您的應用程式傳送電子郵件。 請務必使用 SendGrid 帳戶名稱,而不是您提供 SendGrid 的電子郵件地址。

啟用Email確認

若要啟用電子郵件確認,您將使用下列步驟來修改註冊碼。

  1. [帳戶] 資料夾中,開啟 Register.aspx.cs 程式碼後置並更新 CreateUser_Click 方法來啟用下列醒目提示的變更:

    protected void CreateUser_Click(object sender, EventArgs e)
    {
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var user = new ApplicationUser() { UserName = Email.Text, Email = Email.Text };
        IdentityResult result = manager.Create(user, Password.Text);
        if (result.Succeeded)
        {
            // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
            string code = manager.GenerateEmailConfirmationToken(user.Id);
            string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
            manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");
    
            IdentityHelper.SignIn(manager, user, isPersistent: false);
            IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
        }
        else 
        {
            ErrorMessage.Text = result.Errors.FirstOrDefault();
        }
    }
    
  2. 方案總管中,以滑鼠右鍵按一下Default.aspx,然後選取 [設定為起始頁]。

  3. F5 執行應用程式。顯示頁面之後,按一下 [ 註冊] 連結以顯示 [註冊] 頁面。

  4. 輸入您的電子郵件和密碼,然後按一下 [ 註冊 ] 按鈕,透過 SendGrid 傳送電子郵件訊息。
    專案和程式碼的目前狀態可讓使用者在完成註冊表單後登入,即使他們尚未確認其帳戶也一樣。

  5. 請檢查您的電子郵件帳戶,然後按一下連結以確認您的電子郵件。
    提交註冊表單之後,您將會登入。
    範例網站 - 登入

登入前需要Email確認

雖然您已確認電子郵件帳戶,但此時您不需要按一下驗證電子郵件中包含的連結,才能完全登入。 在下一節中,您將修改要求新使用者有已確認電子郵件的程式碼,才能登入 (經過驗證) 。

  1. Visual Studio 方案總管中,使用下列醒目提示的變更,更新 CreateUser_Click[Accounts]資料夾中所包含Register.aspx.cs程式碼後置中的事件:

    protected void CreateUser_Click(object sender, EventArgs e)
    {
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var user = new ApplicationUser() { UserName = Email.Text, Email = Email.Text };
        IdentityResult result = manager.Create(user, Password.Text);
        if (result.Succeeded)
        {
            // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
            string code = manager.GenerateEmailConfirmationToken(user.Id);
            string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
            manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");
    
            if (user.EmailConfirmed)
            {
              IdentityHelper.SignIn(manager, user, isPersistent: false);
              IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
            } 
            else
            {
              ErrorMessage.Text = "An email has been sent to your account. Please view the email and confirm your account to complete the registration process.";
            }
        }
        else 
        {
            ErrorMessage.Text = result.Errors.FirstOrDefault();
        }
    }
    
  2. LogIn使用下列醒目提示的變更,更新Login.aspx.cs程式碼後置中的 方法:

    protected void LogIn(object sender, EventArgs e)
    {
        if (IsValid)
        {
            // Validate the user password
            var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
            var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();
    
            // Require the user to have a confirmed email before they can log on.
            var user = manager.FindByName(Email.Text);
            if (user != null)
            {
                if (!user.EmailConfirmed)
                {
                    FailureText.Text = "Invalid login attempt. You must have a confirmed email account.";
                    ErrorMessage.Visible = true;
                }
                else
                {
                    // This doen't count login failures towards account lockout
                    // To enable password failures to trigger lockout, change to shouldLockout: true
                    var result = signinManager.PasswordSignIn(Email.Text, Password.Text, RememberMe.Checked, shouldLockout: false);
    
                    switch (result)
                    {
                        case SignInStatus.Success:
                            IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
                            break;
                        case SignInStatus.LockedOut:
                            Response.Redirect("/Account/Lockout");
                            break;
                        case SignInStatus.RequiresVerification:
                            Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}",
                                                        Request.QueryString["ReturnUrl"],
                                                        RememberMe.Checked),
                                          true);
                            break;
                        case SignInStatus.Failure:
                        default:
                            FailureText.Text = "Invalid login attempt";
                            ErrorMessage.Visible = true;
                            break;
                    }
                }
            }
        }          
    }
    

執行應用程式

既然您已實作程式碼來檢查使用者的電子郵件地址是否已確認,您可以同時檢查 [註冊 ] 和 [ 登入 ] 頁面上的功能。

  1. 刪除 AspNetUsers 資料表中包含您想要測試的電子郵件別名的任何帳戶。
  2. 執行應用程式 (F5) ,並確認您必須先確認電子郵件地址,才能註冊為使用者。
  3. 透過剛傳送的電子郵件確認您的新帳戶之前,請先嘗試使用新帳戶登入。
    您會看到您無法登入,而且您必須有確認的電子郵件帳戶。
  4. 確認電子郵件地址之後,請登入應用程式。

密碼復原和重設

  1. 在 Visual Studio 中,從 Forgot [Account] 資料夾中包含的 Forget.aspx.cs程式碼後置方法中移除批註字元,讓方法如下所示:

    protected void Forgot(object sender, EventArgs e)
    {
        if (IsValid)
        {
            // Validate the user's email address
            var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
            ApplicationUser user = manager.FindByName(Email.Text);
            if (user == null || !manager.IsEmailConfirmed(user.Id))
            {
                FailureText.Text = "The user either does not exist or is not confirmed.";
                ErrorMessage.Visible = true;
                return;
            }
            // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
            // Send email with the code and the redirect to reset password page
            string code = manager.GeneratePasswordResetToken(user.Id);
            string callbackUrl = IdentityHelper.GetResetPasswordRedirectUrl(code, Request);
            manager.SendEmail(user.Id, "Reset Password", "Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>.");
            loginForm.Visible = false;
            DisplayEmail.Visible = true;
        }
    }
    
  2. 開啟 Login.aspx 頁面。 取代 loginForm 區段結尾附近的標記,如下所示:

    <%@ Page Title="Log in" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="WebForms002.Account.Login" Async="true" %>
    
    <%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %>
    
    <asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
        <h2><%: Title %>.</h2>
    
        <div class="row">
            <div class="col-md-8">
                <section id="loginForm">
                    <div class="form-horizontal">
                        <h4>Use a local account to log in.</h4>
                        <hr />
                        <asp:PlaceHolder runat="server" ID="ErrorMessage" Visible="false">
                            <p class="text-danger">
                                <asp:Literal runat="server" ID="FailureText" />
                            </p>
                        </asp:PlaceHolder>
                        <div class="form-group">
                            <asp:Label runat="server" AssociatedControlID="Email" CssClass="col-md-2 control-label">Email</asp:Label>
                            <div class="col-md-10">
                                <asp:TextBox runat="server" ID="Email" CssClass="form-control" TextMode="Email" />
                                <asp:RequiredFieldValidator runat="server" ControlToValidate="Email"
                                    CssClass="text-danger" ErrorMessage="The email field is required." />
                            </div>
                        </div>
                        <div class="form-group">
                            <asp:Label runat="server" AssociatedControlID="Password" CssClass="col-md-2 control-label">Password</asp:Label>
                            <div class="col-md-10">
                                <asp:TextBox runat="server" ID="Password" TextMode="Password" CssClass="form-control" />
                                <asp:RequiredFieldValidator runat="server" ControlToValidate="Password" CssClass="text-danger" ErrorMessage="The password field is required." />
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <div class="checkbox">
                                    <asp:CheckBox runat="server" ID="RememberMe" />
                                    <asp:Label runat="server" AssociatedControlID="RememberMe">Remember me?</asp:Label>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <asp:Button runat="server" OnClick="LogIn" Text="Log in" CssClass="btn btn-default" />
                            </div>
                        </div>
                    </div>
                    <p>
                        <asp:HyperLink runat="server" ID="RegisterHyperLink" ViewStateMode="Disabled">Register as a new user</asp:HyperLink>
                    </p>
                    <p>
                        <%-- Enable this once you have account confirmation enabled for password reset functionality --%>
                        <asp:HyperLink runat="server" ID="ForgotPasswordHyperLink" ViewStateMode="Disabled">Forgot your password?</asp:HyperLink>
                    </p>
                </section>
            </div>
    
            <div class="col-md-4">
                <section id="socialLoginForm">
                    <uc:OpenAuthProviders runat="server" ID="OpenAuthLogin" />
                </section>
            </div>
        </div>
    </asp:Content>
    
  3. 開啟 Login.aspx.cs 程式碼後置,並從事件處理常式取消批註以黃色 Page_Load 醒目提示的下列程式程式碼:

    protected void Page_Load(object sender, EventArgs e)
    {
        RegisterHyperLink.NavigateUrl = "Register";
        // Enable this once you have account confirmation enabled for password reset functionality
        ForgotPasswordHyperLink.NavigateUrl = "Forgot";
        OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"];
        var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
        if (!String.IsNullOrEmpty(returnUrl))
        {
            RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl;
        }
    }
    
  4. F5 執行應用程式。顯示頁面之後,按一下 [ 登入] 連結。

  5. 按一下 [忘記密碼嗎?] 連結以顯示 [忘記密碼] 頁面。

  6. 輸入您的電子郵件地址,然後按一下 [ 提交 ] 按鈕,將電子郵件傳送至您的位址,以允許您重設密碼。
    請檢查您的電子郵件帳戶,然後按一下連結以顯示 [ 重設密碼 ] 頁面。

  7. 在 [ 重設密碼] 頁面上,輸入您的電子郵件、密碼和確認的密碼。 然後按 [ 重設 ] 按鈕。
    當您成功重設密碼時,將會顯示 [ 密碼變更 ] 頁面。 現在,您可以使用新的密碼登入。

一旦使用者建立新的本機帳戶,他們就會以電子郵件傳送確認連結,讓他們能夠登入。 如果使用者不小心刪除確認電子郵件,或電子郵件永遠不會送達,他們將需要再次傳送確認連結。 下列程式碼變更示範如何啟用此功能。

  1. 在 Visual Studio 中,開啟 Login.aspx.cs 程式碼後置,並在事件處理常式之後 LogIn 新增下列事件處理常式:

    protected void SendEmailConfirmationToken(object sender, EventArgs e)
    {
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var user = manager.FindByName(Email.Text);
        if (user != null)
        {
            if (!user.EmailConfirmed)
            {
                string code = manager.GenerateEmailConfirmationToken(user.Id);
                string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
                manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");
    
                FailureText.Text = "Confirmation email sent. Please view the email and confirm your account.";
                ErrorMessage.Visible = true;
                ResendConfirm.Visible = false;
            }
        }
    }
    
  2. LogIn藉由變更以黃色醒目提示的程式碼,修改Login.aspx.cs程式碼後置中的事件處理常式,如下所示:

    protected void LogIn(object sender, EventArgs e)
    {
        if (IsValid)
        {
            // Validate the user password
            var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
            var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();
    
            // Require the user to have a confirmed email before they can log on.
            var user = manager.FindByName(Email.Text);
            if (user != null)
            {
                if (!user.EmailConfirmed)
                {
                    FailureText.Text = "Invalid login attempt. You must have a confirmed email address. Enter your email and password, then press 'Resend Confirmation'.";
                    ErrorMessage.Visible = true;
                    ResendConfirm.Visible = true;
                }
                else
                {
                    // This doen't count login failures towards account lockout
                    // To enable password failures to trigger lockout, change to shouldLockout: true
                    var result = signinManager.PasswordSignIn(Email.Text, Password.Text, RememberMe.Checked, shouldLockout: false);
    
                    switch (result)
                    {
                        case SignInStatus.Success:
                            IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
                            break;
                        case SignInStatus.LockedOut:
                            Response.Redirect("/Account/Lockout");
                            break;
                        case SignInStatus.RequiresVerification:
                            Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}",
                                                        Request.QueryString["ReturnUrl"],
                                                        RememberMe.Checked),
                                          true);
                            break;
                        case SignInStatus.Failure:
                        default:
                            FailureText.Text = "Invalid login attempt";
                            ErrorMessage.Visible = true;
                            break;
                    }
                }
            }
        }
    }
    
  3. 新增以黃色醒目提示的程式碼,以更新 Login.aspx 頁面,如下所示:

    <%@ Page Title="Log in" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="WebForms002.Account.Login" Async="true" %>
    
    <%@ Register Src="~/Account/OpenAuthProviders.ascx" TagPrefix="uc" TagName="OpenAuthProviders" %>
    
    <asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
        <h2><%: Title %>.</h2>
    
        <div class="row">
            <div class="col-md-8">
                <section id="loginForm">
                    <div class="form-horizontal">
                        <h4>Use a local account to log in.</h4>
                        <hr />
                        <asp:PlaceHolder runat="server" ID="ErrorMessage" Visible="false">
                            <p class="text-danger">
                                <asp:Literal runat="server" ID="FailureText" />
                            </p>
                        </asp:PlaceHolder>
                        <div class="form-group">
                            <asp:Label runat="server" AssociatedControlID="Email" CssClass="col-md-2 control-label">Email</asp:Label>
                            <div class="col-md-10">
                                <asp:TextBox runat="server" ID="Email" CssClass="form-control" TextMode="Email" />
                                <asp:RequiredFieldValidator runat="server" ControlToValidate="Email"
                                    CssClass="text-danger" ErrorMessage="The email field is required." />
                            </div>
                        </div>
                        <div class="form-group">
                            <asp:Label runat="server" AssociatedControlID="Password" CssClass="col-md-2 control-label">Password</asp:Label>
                            <div class="col-md-10">
                                <asp:TextBox runat="server" ID="Password" TextMode="Password" CssClass="form-control" />
                                <asp:RequiredFieldValidator runat="server" ControlToValidate="Password" CssClass="text-danger" ErrorMessage="The password field is required." />
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <div class="checkbox">
                                    <asp:CheckBox runat="server" ID="RememberMe" />
                                    <asp:Label runat="server" AssociatedControlID="RememberMe">Remember me?</asp:Label>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <asp:Button runat="server" OnClick="LogIn" Text="Log in" CssClass="btn btn-default" />
                                &nbsp;&nbsp;
                                <asp:Button runat="server" ID="ResendConfirm"  OnClick="SendEmailConfirmationToken" Text="Resend confirmation" Visible="false" CssClass="btn btn-default" />
                            </div>
                        </div>
                    </div>
                    <p>
                        <asp:HyperLink runat="server" ID="RegisterHyperLink" ViewStateMode="Disabled">Register as a new user</asp:HyperLink>
                    </p>
                    <p>
                        <%-- Enable this once you have account confirmation enabled for password reset functionality --%>
                        <asp:HyperLink runat="server" ID="ForgotPasswordHyperLink" ViewStateMode="Disabled">Forgot your password?</asp:HyperLink>
                    </p>
                </section>
            </div>
    
            <div class="col-md-4">
                <section id="socialLoginForm">
                    <uc:OpenAuthProviders runat="server" ID="OpenAuthLogin" />
                </section>
            </div>
        </div>
    </asp:Content>
    
  4. 刪除 AspNetUsers 資料表中包含您想要測試的電子郵件別名的任何帳戶。

  5. 執行應用程式 (F5) 並註冊您的電子郵件地址。

  6. 透過剛傳送的電子郵件確認您的新帳戶之前,請先嘗試使用新帳戶登入。
    您會看到您無法登入,而且您必須有確認的電子郵件帳戶。 此外,您現在可以將確認訊息重新傳送至電子郵件帳戶。

  7. 輸入您的電子郵件地址和密碼,然後按 [重新傳送確認] 按鈕。

  8. 一旦您根據新傳送的電子郵件訊息確認電子郵件地址,請登入應用程式。

針對應用程式進行疑難排解

如果您沒有收到包含連結的電子郵件來驗證您的認證:

  • 檢查您的垃圾郵件或垃圾郵件資料夾。
  • 登入您的 SendGrid 帳戶,然後按一下[Email活動] 連結
  • 請務必使用 SendGrid 使用者帳戶名稱作為 Web.config 值,而不是您的 SendGrid 帳戶電子郵件地址。

其他資源