You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iot/projects/IoTNode/Controllers/AccountController.cs

308 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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");
}
}
}