启用 RequireConfiredEmail:
public void ConfigureServices(IServiceCollection services)
{
...
services.Configure<IdentityOptions>(options =>
{
options.Password.RequiredLength = 6;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.SignIn.RequireConfirmedEmail = true;
});
...
}
普通登录中验证邮箱:
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl)
{
model.ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user != null && !user.EmailConfirmed &&
(await _userManager.CheckPasswordAsync(user, model.Password)))
{
ModelState.AddModelError(string.Empty, "您的电子邮箱尚未进行验证。");
return View(model);
}
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false);
if (result.Succeeded)
{
// 防止 Open Redirect
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
ModelState.AddModelError(string.Empty, "登录失败,请重试");
}
return View(model);
}
外部登录中验证邮箱:
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
var loginViewModel = new LoginViewModel
{
ReturnUrl = returnUrl,
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
};
if (remoteError != null)
{
ModelState.AddModelError(string.Empty, $"外部提供程序错误: {remoteError}");
return View("Login", loginViewModel);
}
// 从外部登录提供者,即微软账户体系中,获取关于用户的登录信息。
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ModelState.AddModelError(string.Empty, "加载外部登录信息出错。");
return View("Login", loginViewModel);
}
ApplicationUser user = null;
// 获取邮箱地址
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
if (email != null)
{
// 通过邮箱地址去查询用户是否已存在
user = await _userManager.FindByEmailAsync(email);
// 如果电子邮件没有被确认,返回登录视图与验证错误
if (user != null && !user.EmailConfirmed)
{
ModelState.AddModelError(string.Empty, "您的电子邮箱尚未进行验证。");
return View("Login", loginViewModel);
}
}
// 如果用户之前已经登录过了,会在 AspNetUserLogins 表有对应的记录,这个时候无需创建新的记录,直接使用当前记录登录系统即可。
var signInResult = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey,
isPersistent: false, bypassTwoFactor: true);
if (signInResult.Succeeded)
{
return LocalRedirect(returnUrl);
}
// 如果AspNetUserLogins表中没有记录,则代表用户没有一个本地帐户,这个时候我们就需要创建一个记录了。
if (email != null)
{
if (user == null)
{
user = new ApplicationUser
{
UserName = info.Principal.FindFirstValue(ClaimTypes.Email),
Email = info.Principal.FindFirstValue(ClaimTypes.Email)
};
//如果不存在,则创建一个用户,但是这个用户没有密码。
await _userManager.CreateAsync(user);
// 在AspNetUserLogins表中,添加一行用户数据,然后将当前用户登录到系统中
await _userManager.AddLoginAsync(user, info);
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
// 如果我们获取不到电子邮件地址,我们需要将请求重定向到错误视图中。
ViewBag.ErrorTitle = $"我们无法从提供商:{info.LoginProvider}中解析到您的邮件地址 ";
ViewBag.ErrorMessage = "请通过联系 ltm@ddxc.org 寻求技术支持。";
return View("Error");
}
效果: