我正在this example之后使用ASP.NET Core 2.0探索ASP.NET身份。用户自己注册后,似乎没有机制可以删除他们的帐户。 AccountController.cs
文件未提及删除。
用户应该能够删除他们的帐户,至少是因为GDPR,但删除可能会受到限制,例如他们有购买记录,由于法律原因必须保存多年。那么实现用户自删除的最佳方法是什么?
答案 0 :(得分:1)
I'm not a security specialist so I'll be interested to see what's made of my solution. In ASP.NET Core 2.1 the template will include a self-delete option to conform with GDPR requirements. This will almost certainly be better than the following.
The tack I took was to require the user to enter their password again when deleting their account.
First create a ViewModel in the Models/ManageViewModels
folder:
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; }
}
The [Editable(false)]
is not actually required but it makes it easier to understand when reviewing code months later.
To the ManageController.cs
file add two actions:
[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");
}
This now needs a view in the Manage
folder. I wanted to display the email address and user name, but have made them read-only:
@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")
}
Now the navigation needs sorting out. To the ManageNavPages.cs
file add the following lines:
public static string UserSelfDelete => "UserSelfDelete";
public static string UserSelfDeleteClass(ViewContext viewContext) => PageNavClass(viewContext, UserSelfDelete);
and finally add a link in _ManageNav.cshtml
with the following:
<li class="@ManageNavPages.UserSelfDeleteClass(ViewContext)"><a asp-action="UserSelfDelete">Delete this account</a></li>
答案 1 :(得分:0)
正是由于您指出的原因,大多数网站实际上并没有让用户自行删除。即使他们有办法去除&#34;删除&#34;或&#34;删除&#34;您的帐户,实际发生的是请求删除或删除帐户。这意味着,无论是现场人工干预还是某种自动化流程,都会以流程认可的方式处理它。
换句话说,您不允许用户从字面上对其用户记录发出DELETE查询。您稍后处理他们的请求,确保在实际从数据库中删除任何内容之前存档或以其他方式保留任何必要的记录。