using Application.Domain.Entities; using Application.Models; using Infrastructure.Data; using Infrastructure.Email; using Infrastructure.Extensions; using Infrastructure.Resources; using Infrastructure.Security; using Infrastructure.Web; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Localization; using System; using System.ComponentModel.DataAnnotations; using System.Linq; namespace IoTNode.Controllers { [Authorize] public class AccountController : BaseController { private readonly IConfiguration _cfg; private readonly IRepository _userRepo; private readonly IStringLocalizer _localizer; private readonly IEncryptionService _encryptionService; private readonly IEmailSender _emailSender; public AccountController(IConfiguration configuration, IRepository userRepo, IEncryptionService encryptionService, IStringLocalizer localizer, IEmailSender emaliSender) { this._cfg = configuration; this._userRepo = userRepo; this._encryptionService = encryptionService; this._localizer = localizer; this._emailSender = emaliSender; } #region 权限不足 [AllowAnonymous] public IActionResult AccessDenied(string returnUrl) { return View(model: returnUrl); } #endregion 权限不足 public IActionResult Index() { return View(); } #region 注销 public IActionResult Logout() { HttpContext.Response.Cookies.Delete("jwt"); //HttpContext.SignOutAsync(); return RedirectToAction("Index", "Home"); } #endregion 注销 #region 登录 [HttpGet] [AllowAnonymous] public IActionResult Login(string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; return View(); } [AllowAnonymous] [HttpPost] [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] public IActionResult Login(LoginModel model, string returnUrl = null) { var userName = model.UserName; var password = model.Password; if (ModelState.IsValid) { try { var user = this._userRepo.Table().FirstOrDefault(o => o.UserName == userName); if (user == null) { ModelState.AddModelError(nameof(model.UserName), this._localizer["用户不存在"]); } else { if (user.PasswordHash == this._encryptionService.CreatePasswordHash(password, user.SecurityStamp)) { HttpContext.SignIn(model.UserName, model.RememberMe, _cfg); if (string.IsNullOrEmpty(returnUrl)) { returnUrl = Url.Action("Index", "Home"); } ViewBag.Url = returnUrl; return Redirect(returnUrl); } else { ModelState.AddModelError(nameof(model.Password), this._localizer["密码错误"]); } } } catch (Exception ex) { ex.PrintStack(); ModelState.AddModelError("", ex.Message); } } ViewData["ReturnUrl"] = returnUrl; return View(model); } #endregion 登录 #region 注册 [AllowAnonymous] public IActionResult Register() { return View(); } [HttpPost] [AllowAnonymous] [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] public IActionResult Register(RegisterModel model) { if (User.Identity.IsAuthenticated) { return RedirectTo("Index", "Home", "当前已登录,请退出"); } if (ModelState.IsValid) { try { var user = new User().From(model); user.SecurityStamp = this._encryptionService.CreateSalt(); user.PasswordHash = this._encryptionService.CreatePasswordHash(model.Password, user.SecurityStamp); user.Email = model.Email; this._userRepo.Add(user); this._userRepo.SaveChanges(); return RedirectTo("Login", "Account", "注册成功"); } catch (Exception ex) { ex.PrintStack(); ModelState.AddModelError("", ex.Message); } } return View(model); } #endregion 注册 #region 修改密码 public IActionResult ChangePassword() { return View(); } [HttpPost] [ValidateAntiForgeryToken] [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] public IActionResult ChangePassword(ChangePasswordModel model) { if (ModelState.IsValid) { try { var user = this._userRepo.Table().FirstOrDefault(o => o.UserName == User.Identity.Name); if (user.PasswordHash == this._encryptionService.CreatePasswordHash(model.OldPassword, user.SecurityStamp)) { user.PasswordHash = this._encryptionService.CreatePasswordHash(model.NewPassword, user.SecurityStamp); this._userRepo.SaveChanges(); return RedirectTo(rawMesage: "密码修改成功"); } else { ModelState.AddModelError(nameof(model.OldPassword), "当前密码输入错误"); } } catch (Exception ex) { ex.PrintStack(); ModelState.AddModelError("", ex.Message); } } return View(model); } #endregion 修改密码 #region 忘记密码 [AllowAnonymous] public IActionResult ForgotPassword() { return View(); } [HttpPost] [AllowAnonymous] public IActionResult ForgotPassword(ForgotPasswordModel model) { if (ModelState.IsValid) { var url = Url.FullAction(nameof(ResetPassword), "Account", new { id = this._encryptionService.EncryptObject($"{model.Email}&{DateTime.UtcNow.AddMinutes(10).ToUnixTimeMilliseconds()}") }); this._emailSender.SendMail(this._cfg["Name"], this._cfg["EmailUser"], model.Email, $"{this._cfg["Name"]}找回密码", $"点击链接或复制链接到浏览器中,10分钟内有效: {url} ", this._cfg["EmailHost"], this._cfg.GetValue("EmailPort"), this._cfg["EmailUser"], this._cfg["EmailPassword"]); Console.WriteLine(url); ViewBag.Message = "重设密码邮件已经发送到您的邮箱中"; } return View(model); } [AllowAnonymous] public IActionResult ResetPassword(string id) { var values = this._encryptionService.DecryptObject(id).Split('&'); var timestamp = long.Parse(values[1]); if (DateTime.UtcNow.AddMinutes(10).ToUnixTimeMilliseconds() > timestamp) { return RedirectTo(controller: "Home", rawMesage: "链接已失效"); } return View(new ResetPasswordModel { Id = id }); } [AllowAnonymous] [HttpPost] public IActionResult ResetPassword(ResetPasswordModel model) { if (ModelState.IsValid) { var values = this._encryptionService.DecryptObject(model.Id).Split('&'); var email = values[0]; var timestamp = long.Parse(values[1]); if (DateTime.UtcNow.AddMinutes(10).ToUnixTimeMilliseconds() > timestamp) { return RedirectTo(controller: "Home", rawMesage: "链接已失效"); } var user = this._userRepo.Table().FirstOrDefault(o => o.Email == email); user.PasswordHash = this._encryptionService.CreatePasswordHash(model.Password, user.SecurityStamp); this._userRepo.SaveChanges(); return RedirectTo(action: "Login", rawMesage: "密码设置成功"); } return View(model); } #endregion 忘记密码 #region Ajax验证 [AllowAnonymous] public JsonResult UserNameNotUsed([Required]string userName) { if (ModelState.IsValid) { return Json(!this._userRepo.ReadOnlyTable().Any(o => o.UserName == userName)); } return Json("用户名不能为空"); } [AllowAnonymous] public JsonResult EmailNotUsed([Required]string email) { if (ModelState.IsValid) { return Json(!this._userRepo.ReadOnlyTable().Any(o => o.Email == email)); } return Json("邮箱不能为空"); } [AllowAnonymous] public JsonResult HasEmail([Required]string email) { if (ModelState.IsValid) { var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.Email == email); if (user != null) { return Json(true); } return Json("邮箱不存在"); } return Json("邮箱不能为空"); } #endregion Ajax验证 [Route("/login")] [AllowAnonymous] public IActionResult Test() { var userName = "super"; HttpContext.SignIn(userName, true, _cfg); return RedirectToAction("Index", "Home"); } } }