|
|
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<User> _userRepo;
|
|
|
private readonly IStringLocalizer<Resource> _localizer;
|
|
|
private readonly IEncryptionService _encryptionService;
|
|
|
private readonly IEmailSender _emailSender;
|
|
|
|
|
|
public AccountController(IConfiguration configuration,
|
|
|
IRepository<User> userRepo,
|
|
|
IEncryptionService encryptionService,
|
|
|
IStringLocalizer<Resource> 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分钟内有效: <a href=\"{url}\">{url}</a> ", this._cfg["EmailHost"], this._cfg.GetValue<int>("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<string>(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<string>(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");
|
|
|
}
|
|
|
}
|
|
|
} |