我不是安全专家,所以我有兴趣了解我的解决方案是什么。在 ASP.NET Core 2.1 中,模板将包含一个自删除选项以符合 GDPR 要求。这几乎肯定会比以下更好。
我采取的策略是要求用户在删除帐户时再次输入密码。
首先在Models/ManageViewModels文件夹中创建一个ViewModel:
public class UserSelfDeleteViewModel
{
[Editable(false)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Editable(false)]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[Display(Name = "Password")]
[DataType(DataType.Password)]
public string Password { get; set; }
}
[Editable(false)] 实际上并不是必需的,但它可以让您在数月后查看代码时更容易理解。
在ManageController.cs 文件中添加两个操作:
[HttpGet]
public async Task<IActionResult> UserSelfDelete()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
// Validate business rules to ensure self-deletion is allowed, though it would
// be a good idea to tell the user why their account cannot be deleted
var userSelfDelete = new UserSelfDeleteViewModel
{
Email = user.Email,
UserName = user.UserName
};
return View(userSelfDelete);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UserSelfDelete(UserSelfDeleteViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (await _userManager.CheckPasswordAsync(user, model.Password) == false)
{
ModelState.AddModelError("Password", "Incorrect password entered");
return View(model);
}
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out prior to account deletion.");
await _userManager.DeleteAsync(user);
return RedirectToAction(nameof(HomeController.Index), "Home");
}
这现在需要Manage 文件夹中的视图。我想显示电子邮件地址和用户名,但已将它们设为只读:
@model UserSelfDeleteViewModel
@{
ViewData["Title"] = "Delete this account";
}
<h4>@ViewData["Title"]</h4>
<div class="row">
<div class="col-md-6">
<form method="post">
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" readonly="readonly" />
</div>
<div class="form-group">
<label asp-for="UserName"></label>
<input asp-for="UserName" class="form-control" readonly="readonly" />
</div>
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" autocomplete="new-password" autofill=""/>
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-default">Delete your account</button>
</form>
</div>
</div>
@section Scripts {
@await Html.PartialAsync("_ValidationScriptsPartial")
}
现在导航需要整理。在ManageNavPages.cs 文件中添加以下行:
public static string UserSelfDelete => "UserSelfDelete";
public static string UserSelfDeleteClass(ViewContext viewContext) => PageNavClass(viewContext, UserSelfDelete);
最后在_ManageNav.cshtml 中添加一个链接:
<li class="@ManageNavPages.UserSelfDeleteClass(ViewContext)"><a asp-action="UserSelfDelete">Delete this account</a></li>