快速掌握 ASP.NET 身份認證框架 Identity - 通過郵件重置密碼

這是 ASP.NET Core Identity 系列的第四篇文章,上一篇文章講解了如何在 ASP.NET Core Identity 中實現用戶登錄與登出。

這篇文章講一講如何在 ASP.NET Core Identity 中通過郵件服務實現用戶賬號的密碼重置。

點擊上方或后方藍字,閱讀 ASP.NET Core Identity 系列合集。

本篇文章的示例項目:https://github.com/zilor-net/IdentitySample/tree/main/Sample04

1c69fcedc691a29959828e20e65f43d6.png

密碼重置

用戶管理中最常見的功能就是密碼重置。

密碼重置過程,不應該涉及系統管理員,因為用戶本身應該能夠獨立完成整個過程。

通常,登錄頁面上都會為用戶提供忘記密碼的鏈接,以用來重置密碼,這就是我們接下來要實現的功能。

簡單地解釋一下密碼重置過程:

  1. 用戶單擊忘記密碼鏈接,然后跳轉到帶有電子郵件字段的頁面。

  2. 用戶填寫該字段后,應用程序會向該電子郵件發送密碼重置的連接。

  3. 用戶通過單擊電子郵件的密碼重置鏈接,此時會使用密碼重置令牌,重定向到密碼重置頁面。

  4. 用戶填充表單中的所有字段后,應用程序將重置密碼,用戶再被重定向到登錄頁面或主頁。

郵件服務

示例項目中已經集成了郵件服務 「EmailService」 ,以用來幫助我們發送郵件,

具體的郵件發送的實現不是這個系列的主題,就不做過多的闡述。大家可以自己查看示例中「EmailService」項目中關于郵件發送的代碼。

郵件服務通過擴展方法注冊到了依賴注入框架中,其具體配置在 「appsettings.json」 中。

忘記密碼

首先,我們需要創建 「忘記密碼」 的視圖。

「Models」 文件夾中,創建一個 「ForgotPasswordModel」 類:

public?class?ForgotPasswordModel
{[Display(Name?=?"電子郵箱")][Required(ErrorMessage?=?"電子郵箱不能為空")][EmailAddress(ErrorMessage?=?"電子郵箱格式不正確")]public?string?Email?{?get;?set;?}
}

它會用在「忘記密碼」視圖中,這里我們只需要獲取用戶的電子郵件,所以這里只有一個 「Email」 屬性。

接下來,在 「Account」 控制器中,創建兩個操作方法:

[HttpGet]
public?IActionResult?ForgotPassword()
{return?View();
}[HttpPost]
[ValidateAntiForgeryToken]
public?async?Task<IActionResult>?ForgotPassword(ForgotPasswordModel?forgotPasswordModel)
{return?View(forgotPasswordModel);
}public?IActionResult?ForgotPasswordConfirmation()
{return?View();
}

這個套路我們已經很熟悉了,第一個 「ForgotPassword」 只是為了創建視圖;第二個 「ForgotPassword」 是為了實現邏輯;「ForgotPasswordConfirmation」 則是返回確認視圖。

接下來,再依次創建相關的視圖:

71da9bc00456a7be63d6f51ae76777d9.png
<h1>ForgotPasswordConfirmation</h1><p>重置密碼的鏈接已經發送到您的電子郵箱!
</p>

然后在 「Login」 視圖中,添加忘記密碼的鏈接:

<div?class="form-group"><a?asp-action="ForgotPassword">忘記密碼</a>
</div>

現在,讓我們來實現忘記密碼的邏輯:

[HttpPost]
[ValidateAntiForgeryToken]
public?async?Task<IActionResult>?ForgotPassword([FromServices]IEmailSender?emailSender,?ForgotPasswordModel?forgotPasswordModel)
{if?(!ModelState.IsValid)return?View(forgotPasswordModel);var?user?=?await?_userManager.FindByEmailAsync(forgotPasswordModel.Email);if?(user?==?null)return?RedirectToAction(nameof(ForgotPasswordConfirmation));var?token?=?await?_userManager.GeneratePasswordResetTokenAsync(user);var?callback?=?Url.Action(nameof(ResetPassword),?"Account",?new?{?token,?email?=?user.Email?},?Request.Scheme);var?message?=?new?Message(new?string[]?{?user.Email?},?"重置密碼",?callback,?null);await?emailSender.SendEmailAsync(message);return?RedirectToAction(nameof(ForgotPasswordConfirmation));
}

如果模型有效,就通過用戶的電子郵件,從數據庫中獲取用戶。

如果不存在,只需將該用戶,重定向到郵件已發送的確認頁面,而不是創建用戶不存在的消息。

這么做主要是出于安全考慮,以防止有人利用這個功能,驗證用戶名的有效性。

如果用戶存在,就通過 「GeneratePasswordResetTokenAsync」 方法,生成一個令牌,并創建一個回調鏈接,到我們將用于重置密碼邏輯的操作。

最后,我們向用戶提供的電子郵件,發送郵件消息,并將用戶重定向到確認頁面。

現在,程序還無法創建令牌,因為我們還沒有注冊令牌服務,這需要在注冊 「Identity」 方法時進行注冊:

builder.Services.AddIdentity<User,?IdentityRole>().AddEntityFrameworkStores<ApplicationContext>().AddDefaultTokenProviders();

如果我們希望密碼重置令牌只在有限的時間內有效,例如: 2小時,那我們還需要配置令牌生存期:

builder.Services.Configure<DataProtectionTokenProviderOptions>(opt?=>opt.TokenLifespan =?TimeSpan.FromHours(2));

重置密碼

接著,我們來實現 「ResetPassword」 重置密碼的操作方法,創建一個 「ResetPasswordModel」 類:

public?class?ResetPasswordModel
{[Display(Name?=?"密碼")][Required(ErrorMessage?=?"密碼不能為空")][DataType(DataType.Password)]public?string?Password?{?get;?set;?}[Display(Name?=?"確認密碼")][DataType(DataType.Password)][Compare("Password",?ErrorMessage?=?"密碼與確認密碼不匹配。")]public?string?ConfirmPassword?{?get;?set;?}public?string?Email?{?get;?set;?}public?string?Token?{?get;?set;?}
}

然后,在 「Account」 控制器中,創建 「ResetPassword」 操作方法:

[HttpGet]
public?IActionResult?ResetPassword(string?token,?string?email)
{var?model?=?new?ResetPasswordModel?{?Token?=?token,?Email?=?email?};return?View(model);
}[HttpPost]
[ValidateAntiForgeryToken]
public?async?Task<IActionResult>?ResetPassword(ResetPasswordModel?resetPasswordModel)
{return?View();
}[HttpGet]
public?IActionResult?ResetPasswordConfirmation()
{return?View();
}

這里與 「ForgotPassword」 操作類似。

「HttpGet」ResetPassword操作會接受來自電子郵件中,密碼重置連接的請求,提取令牌和電子郵件,并創建一個視圖。

「HttpPost」ResetPassword操作是處理重置密碼的邏輯。

ResetPasswordConfirmation只是一個密碼重置的確認視圖。

依次創建這些視圖:

ef15eeda40f883da8b5aea60a7e6d735.png

需要注意的是,我們需要把 「Email」「Token」 兩個字段隱藏起來,因為這兩個值由應用提供,不需要用戶設置:

<input?type="hidden"?asp-for="Email"?class="form-control"?/>
<input?type="hidden"?asp-for="Token"?class="form-control"?/>

「ResetPasswordConfirmation」 視圖:

<h1>ResetPasswordConfirmation</h1>
<p>您的密碼已經重置.?請點擊這里?<a?asp-action="Login">?登錄?</a>!
</p>

最后,再來修改 「POST」ResetPassword 操作方法:

[HttpPost]
[ValidateAntiForgeryToken]
public?async?Task<IActionResult>?ResetPassword(ResetPasswordModel?resetPasswordModel)
{if?(!ModelState.IsValid)return?View(resetPasswordModel);var?user?=?await?_userManager.FindByEmailAsync(resetPasswordModel.Email);if?(user?==?null)RedirectToAction(nameof(ResetPasswordConfirmation));var?resetPassResult?=?await?_userManager.ResetPasswordAsync(user,?resetPasswordModel.Token,?resetPasswordModel.Password);if(!resetPassResult.Succeeded){foreach?(var?error?in?resetPassResult.Errors){ModelState.TryAddModelError(error.Code,?error.Description);}return?View();}return?RedirectToAction(nameof(ResetPasswordConfirmation));
}

首先,檢查模型的有效性,以及用戶是否存在于數據庫中。

之后,使用 「ResetPasswordAsync」 方法,執行密碼重置操作。

如果操作失敗,就向模型狀態添加錯誤并返回視圖。否則,我們將用戶重定向到確認頁面。

需要注意的是,如果想要測試最終效果,郵件服務的配置以及用戶的郵件地址都必須是真實有效的。

小結

現在,我們已經實現了用戶通過電子郵件,重置密碼的功能,下篇文章將會講解如何在用戶注冊時,必須確認電子郵件是否有效的功能。

更多精彩內容,請關注我▼▼

d4c04b351f225756b5b069f5f4d640b1.gif

如果喜歡我的文章,那么

在看和轉發是對我最大的支持!

(戳下面藍字閱讀)

e241706d9b4757affda5ccba11f4ad6b.png

推薦關注微信公眾號:碼俠江湖

? ? ? ? ? ? ? ? ? ? ? ??d387e970d609b4285ba5cf0be12a66f4.png覺得不錯,點個在看再走喲

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/news/285579.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/285579.shtml
英文地址,請注明出處:http://en.pswp.cn/news/285579.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[.net 面向對象程序設計深入](4)MVC 6 —— 談談MVC的版本變遷及新版本6.0發展方向...

[.net 面向對象程序設計深入]&#xff08;4&#xff09;MVC 6 ——談談MVC的版本變遷及新版本6.0發展方向 1.關于MVC 在本篇中不再詳細介紹MVC的基礎概念&#xff0c;這些東西百度要比我寫的全面多了&#xff0c;MVC從1.0到5.0的時間也不短了&#xff0c;很多人只是按照范例去使…

C語言試題101之輸入三個整數 x,y,z,請把這三個數由小到大輸出

?作者簡介:大家好我是碼莎拉蒂,CSDN博客專家?????? ??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 1、題目 題目:輸入三個整數 x,y,z,請把這三個數由小到大輸出 分析:想辦法把最小的數放到 x 上,先…

[轉]史上最全的后端技術大全,你都了解哪些技術呢?

導語&#xff1a;工欲善其事&#xff0c;必先利其器&#xff1b;士欲宣其義&#xff0c;必先讀其書。后臺開發作為互聯網技術領域的掌上明珠&#xff0c;一直都是開發者們的追逐的高峰。本文將從后臺開發所涉及到的技術術語出發&#xff0c;基于系統開發、架構設計、網絡通信等…

【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(二)

【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(一) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(二) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(三) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(四) 【專升本計算機】2021…

DB2錯誤碼信息

00 完全成功完成 表 3 01 警告 表 4 02 無數據 表 5 07 動態 SQL 錯誤 表 6 08 連接異常 表 7 09 觸發操作異常 表 8 0A 功能部件不受支持 表 9 0D 目標類型規范無效 表 10 0F 無效標記 表 11 0K RESIGNAL 語句無效 表 12 0N SQL/XML 映射錯誤 表 13 20 找不到 CASE…

WPF 開源控件庫Extended WPF Toolkit介紹(經典)

01—Extended WPF Toolkit介紹Extended WPF Toolkit 可以說是WPF Toolkit 的一個補充&#xff0c;Extended WPF Toolkit包含了標準的WPF Toolkit里沒有的Windows Presentation Foundation&#xff08;WPF&#xff09;控件、工具和組件。Extended WPF Toolkit是創建下一代Window…

vi和vim 的常用操作

&#xff1a;q! 強制退出 到文件末尾: ESC shift G : 到文件頭: G G&#xff1a; 整塊模式 快捷鍵 【不使用鼠標&#xff0c;來選擇塊】 v 字符選擇&#xff0c;會將光標經過的地方反白選擇&#xff01;V(大寫) 行選擇&#xff0c;會將光標經過…

C語言試題102之用*號輸出字母 C 的圖案

?作者簡介:大家好我是碼莎拉蒂,CSDN博客專家?????? ??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 1、題目 題目:用號輸出字母 C 的圖案 分析:可先用’號在紙上寫出字母 C,再分行輸出。 2 、溫馨提…

【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(三)

【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(一) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(二) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(三) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(四) 【專升本計算機】2021…

WPF 用代碼實現WrapPanel右側自動對齊(解決多余空白問題)

未處理前效果&#xff1a; 處理后效果&#xff1a; <Border Background"{StaticResource BorderBg}" BorderThickness"2" BorderBrush"{StaticResource BorderBrush}" CornerRadius"5" Padding"5" x:Name"SvK…

.NET 中的引用程序集

.NET 中的引用程序集Intro在 .NET 里有一種特殊的程序集叫做 ReferenceAssembly(引用程序集)&#xff0c;引用程序集&#xff08;Reference Assemblies&#xff09; 是一種特殊類型的程序集&#xff0c;它只包含表示庫的公共 API 所需的最少元數據量。它們包括在生成工具中引用…

【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(四)

【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(一) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(二) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(三) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(四) 【專升本計算機】2021…

14.6.3.1 The InnoDB Buffer Pool

14.6.3.1 The InnoDB Buffer PoolInnoDB 保持一個存儲區域被稱為buffer pool 用于cache數據和索引在內存里,知道InnoDB buffer pool 如何工作,利用它來保持頻繁訪問的數據在內存里,是MYSQL 調優的一個重要方面。你可以配置InnoDB buffer pool的各個方面來改善性能:理想情況下,你…

C語言試題105之要求輸出國際象棋棋盤

?作者簡介:大家好我是碼莎拉蒂,CSDN博客專家?????? ??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 1、題目 題目:要求輸出國際象棋棋盤。 分析:用 i 控制行,j 來控制列,根據 i+j 的和的變化來控制…

一個js的動畫,以前以為只有flash可以實現

11年剛干這行的時候&#xff0c;看到這種什么百葉窗的動畫&#xff0c;以為都是flash實現的&#xff0c;最近突然靈光一閃&#xff0c;想到了用js實現&#xff08;雖然我不是做前端的&#xff0c;本人做.net&#xff09;。代碼雖然實現了&#xff0c;但是比較亂&#xff0c;先上…

[轉]docker入門(利用docker部署web應用)

前言:本課程是在慕課網上學習 第一個docker化的java應用 課程時所做的筆記,供本人復習之用 目錄 第一章 什么是docker 1.1 docker的發展史 1.2 docker國內應用史 1.3 什么是Docker 第二章 了解docker 2.1 docker思想 2.1.1 集裝箱 2.1.2 標準化 2.1.3 隔離 2.2 dock…

【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(五)

【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(一) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(二) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(三) 【專升本計算機】2021年甘肅省專升本計算機全真模擬試題(四) 【專升本計算機】2021…

如何讓 EF Core 6 支持 DateOnly 類型

前言上次&#xff0c;我們發現《DateOnly 和 TimeOnly 類型居然不能序列化》。但問題還不僅僅如此。問題重現假設有下列實體類&#xff1a;public class User {public int Id { get; set; }public string Name { get; set; } public DateOnly Birthday { get; set; } }由…

yii2筆記: 單元測試

使用composer方式安裝yii2-app-basic (https://github.com/yiisoft/yii2-app-basic/blob/master/README.md) 裝好后既可以使用 建一個Model文件EntryForm.php在models目錄下 <?phpnamespace app\models;use Yii; use yii\base\Model;class EntryForm extends Model {public…

[轉]Python 列表(List) 的三種遍歷(序號和值)方法

if __name__ __main__:list [html, js, css, python]for i in list:print(list.index(i), i)# 方法1print( 遍歷列表方法1&#xff1a;)for i in list:print ("序號&#xff1a;%s 值&#xff1a;%s" % (list.index(i) 1, i))print (\n遍歷列表方法2&#xff1a;)…