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/UserCenter/Controllers/AccountController.cs

925 lines
34 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden 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.Application.Services.Settings;
using Infrastructure.Data;
using Infrastructure.Email;
using Infrastructure.Extensions;
using Infrastructure.Security;
using Infrastructure.Sms;
using Infrastructure.Web;
using Infrastructure.Web.DataAnnotations;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
namespace UserCenter.Controllers
{
[Authorize]
public class AccountController : BaseController
{
private readonly IConfiguration _cfg;
private readonly ISettingService _settingService;
private readonly IRepository<User> _userRepo;
private readonly IRepository<Site> _siteRepo;
private readonly IEncryptionService _encryptionService;
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
//private readonly FaceRecognitionService _frs;
public AccountController(IConfiguration cfg,
ISettingService settingService,
IRepository<User> userRepo,
IRepository<Site> siteRepo,
IEncryptionService encryptionService,
IEmailSender emaliSender,
ISmsSender smsSender
//FaceRecognitionService frs
)
{
this._cfg = cfg;
this._settingService = settingService;
this._userRepo = userRepo;
this._siteRepo = siteRepo;
this._encryptionService = encryptionService;
this._emailSender = emaliSender;
this._smsSender = smsSender;
//this._frs = frs;
}
#region 用户中心
public IActionResult Index()
{
return View(this._siteRepo.ReadOnlyTable().ToList());
}
#endregion 用户中心
#region 注销
public IActionResult Logout(string returnUrl = null)
{
var username = User.Identity.Name;
var urls = new List<string>();
var list = this._siteRepo.ReadOnlyTable().ToList();
foreach (var site in list)
{
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
var sign = string.Concat(username, timestamp, site.Key).Md5();
var url = site.Logout
.SetParam(nameof(username), username)
.SetParam(nameof(timestamp), timestamp)
.SetParam(nameof(sign), sign);
urls.Add(url);
}
if (string.IsNullOrEmpty(returnUrl))
{
returnUrl = Url.Action("Index", "Home");
}
ViewBag.Url = returnUrl;
HttpContext.JwtSignOut();
return View("JsonpLogout", urls);
}
#endregion 注销
#region 登录
[AllowAnonymous]
[HttpGet]
public IActionResult Login(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[AllowAnonymous]
[HttpPost]
public IActionResult Login(LoginModel model, string returnUrl = null)
{
var userName = model.UserName;
var password = model.Password;
var key = "";
var message = "";
if (ModelState.IsValid)
{
try
{
var user = this._userRepo.Table().FirstOrDefault(o => o.UserName == userName);
if (user == null)
{
key = nameof(model.UserName);
message = "用户ä¸<C3A4>存在";
}
else
{
var maxAccessFailedCount = Convert.ToInt32(this._settingService.GetSetting("MaxFailedAccessAttemptsBeforeLockout").Value);
var lockoutEndMinutes = Convert.ToInt32(this._settingService.GetSetting("DefaultAccountLockoutMinutes").Value);
if (user.LockoutEnabled)//对已å<C2B2>¯ç”¨ç™»å½•é”<C3A9>å®šçš„ç”¨æˆ·ï¼Œå¦æžœå½“å‰<C3A5>登录时间超出é”<C3A9>定时间,先解除é”<C3A9>定状æ€<C3A6>
{
if (user.LockoutEnd.HasValue && DateTime.UtcNow > user.LockoutEnd)
{
user.LockoutEnd = null;
user.AccessFailedCount = 0;
this._userRepo.SaveChanges();
}
}
var success = false;
if (user.LockoutEnabled)//对å<C2B9>¯ç”¨ç™»å½•é”<C3A9>定的用户è¿è¡ŒéªŒè¯<C3A8>
{
if (user.LockoutEnd.HasValue == false)
{
if (user.PasswordHash == this._encryptionService.CreatePasswordHash(password, user.SecurityStamp))
{
user.LockoutEnd = null;
user.AccessFailedCount = 0;
success = true;
}
else
{
user.AccessFailedCount += 1;
if (user.AccessFailedCount >= maxAccessFailedCount)
{
user.LockoutEnd = DateTime.UtcNow.AddMinutes(lockoutEndMinutes);
}
}
this._userRepo.SaveChanges();
}
}
else//对未å<C2AA>¯ç”¨ç™»å½•é”<C3A9>定的用户è¿è¡ŒéªŒè¯<C3A8>
{
if (user.PasswordHash == this._encryptionService.CreatePasswordHash(password, user.SecurityStamp))
{
success = true;
}
}
if (success)
{
HttpContext.JwtSignIn(model.UserName, model.RememberMe, _cfg);
if (string.IsNullOrEmpty(returnUrl))
{
returnUrl = Url.Action("Index", "Home");
}
ViewBag.Url = returnUrl;
var urls = new List<string>();
var list = this._siteRepo.ReadOnlyTable().ToList();
foreach (var site in list)
{
var username = user.UserName;
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
var sign = string.Concat(userName, timestamp, site.Key).Md5();
var url = site.Login
.SetParam(nameof(username), username)
.SetParam(nameof(user.NickName), user.NickName)
.SetParam(nameof(user.Avatar), user.Avatar)
.SetParam(nameof(timestamp), timestamp)
.SetParam("rememberme", model.RememberMe)
.SetParam(nameof(sign), sign);
urls.Add(url);
}
Response.Headers.Remove("Location");
return View("JsonpLogin", urls);
}
else
{
if (user.LockoutEnabled && user.LockoutEnd.HasValue)
{
key = nameof(model.UserName);
message = $"用户被é”<C3A9>定,请于{user.LockoutEnd.Value.ToLocalTime():HH:mm}å<>Žé‡<C3A9>试";
}
else
{
key = nameof(model.Password);
message = "密ç <C3A7>错误";
}
}
}
}
catch (DbUpdateException ex)
{
ex.PrintStack();
message = ex.Message;
}
}
ModelState.AddModelError(key, message);
ViewData["ReturnUrl"] = returnUrl;
return View(model);
}
#endregion 登录
#region 注册
[AllowAnonymous]
public JsonResult UserNameNotUsed([Required] string userName)
{
if (ModelState.IsValid)
{
return Json(!this._userRepo.ReadOnlyTable().Any(o => o.UserName == userName));
}
return Json("用户å<C2B7><C3A5>ä¸<C3A4>能为空");
}
#endregion 注册
#region 邮箱注册
[AllowAnonymous]
public IActionResult Register(string returnUrl = null)
{
if (this.RegisterDisabled())
{
return RedirectTo("Index", "Home", "当å‰<C3A5>未开放注册");
}
if (User.Identity.IsAuthenticated)
{
return RedirectTo("Index", "Home", "当å‰<C3A5>已登录,请退出");
}
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult Register(RegisterModel model, string returnUrl = null)
{
if (this._cfg.GetValue<bool>("RegisterDisabled"))
{
return RedirectTo("Index", "Home", "当å‰<C3A5>未开放注册");
}
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.PasswordConfirmed = true;
user.EmailConfirmed = true;
this._userRepo.Add(user);
this._userRepo.SaveChanges();
if (returnUrl == null)
{
returnUrl = Url.Action("Index", "Home");
}
return RedirectTo("Login", "Account", "注册æˆ<C3A6>功", new { returnUrl });
}
catch (Exception ex)
{
ex.PrintStack();
ModelState.AddModelError("", ex.Message);
}
}
return View(model);
}
[AllowAnonymous]
public JsonResult EmailNotUsed([Required] string email)
{
if (ModelState.IsValid)
{
return Json(!this._userRepo.ReadOnlyTable().Any(o => o.Email == email));
}
return Json(®ç®±ä¸<C3A4>能为空");
}
[AllowAnonymous]
public JsonResult SendCodeToEmail([Required] string email)
{
if (ModelState.IsValid)
{
try
{
string code = this.GetRandomCode();
this.SendCodeToEmail(email, code);
var seconds = this.GetCaptchaSeconds();
this.HttpContext.Session.Set(CodeCaptchaModel.Key, new CodeCaptchaModel
{
ExpireDateUtc = DateTime.UtcNow.AddSeconds(seconds),
MaxErrorLimit = 5,
Captcha = code
});
return Json(new { success = true, data = seconds });
}
catch (Exception ex)
{
ex.PrintStack();
return Json(new { success = false, data = ex.Message });
}
}
return Json(new { success = false, data = ®ç®±ä¸<C3A4>能为空" });
}
#endregion 邮箱注册
#region æ‰æœºå<C2BA>·æ³¨å†Œ
[AllowAnonymous]
public IActionResult RegisterByPhoneNumber(string returnUrl = null)
{
if (this._cfg.GetValue<bool>("RegisterDisabled"))
{
return RedirectTo("Index", "Home", "当å‰<C3A5>未开放注册");
}
if (User.Identity.IsAuthenticated)
{
return RedirectTo("Index", "Home", "当å‰<C3A5>已登录,请退出å<C2BA>Žå†<C3A5>注册");
}
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult RegisterByPhoneNumber(RegisterPhoneNumberModel model, string returnUrl = null)
{
if (this._cfg.GetValue<bool>("RegisterDisabled"))
{
return RedirectTo("Index", "Home", "当å‰<C3A5>未开放注册");
}
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.PasswordConfirmed = true;
user.PhoneNumberConfirmed = true;
this._userRepo.Add(user);
this._userRepo.SaveChanges();
if (returnUrl == null)
{
returnUrl = Url.Action("Index", "Home");
}
return RedirectTo("Login", "Account", "注册æˆ<C3A6>功", new { returnUrl });
}
catch (DbUpdateException ex)
{
ex.PrintStack();
ModelState.AddModelError("", ex.Message);
}
}
return View(model);
}
[AllowAnonymous]
public JsonResult PhoneNumberNotUsed([Required] string phoneNumber)
{
if (ModelState.IsValid)
{
return Json(!this._userRepo.ReadOnlyTable().Any(o => o.PhoneNumber == phoneNumber));
}
return Json(®ç®±ä¸<C3A4>能为空");
}
[AllowAnonymous]
public JsonResult SendCodeToPhoneNumber([Required] string phoneNumber)
{
if (ModelState.IsValid)
{
try
{
this._smsSender.Send(phoneNumber, out string code);
var seconds = this.GetCaptchaSeconds();
this.HttpContext.Session.Set(CodeCaptchaModel.Key, new CodeCaptchaModel
{
ExpireDateUtc = DateTime.UtcNow.AddSeconds(seconds),
MaxErrorLimit = 5,
Captcha = code
});
return Json(new { success = true, data = seconds });
}
catch (Exception ex)
{
ex.PrintStack();
return Json(new { success = false, data = ex.Message });
}
}
return Json(new { success = false, data = "æ‰æœºå<C2BA>·ä¸<C3A4>能为空" });
}
#endregion æ‰æœºå<C2BA>·æ³¨å†Œ
#region é‡<C3A9>设密ç <C3A7>
[AllowAnonymous]
public IActionResult ForgotPassword()
{
if (User.Identity.IsAuthenticated)
{
return RedirectTo("Index", "Home", "当å‰<C3A5>已登录,请退出å<C2BA>Žé‡<C3A9>试");
}
return View();
}
[HttpPost]
[AllowAnonymous]
public IActionResult ForgotPassword(ResetPasswordModel model)
{
if (ModelState.IsValid)
{
if (this._userRepo.ReadOnlyTable().Any(o => o.UserName == model.UserName))
{
this.HttpContext.Session.Remove(ResetPasswordModel.Key);
return RedirectTo(nameof(Login), rawMesage: "密ç <C3A7>修改æˆ<C3A6>功,请é‡<C3A9>æ°ç™»å½•");
}
ModelState.AddModelError(nameof(model.UserName), "用户å<C2B7><C3A5>ä¸<C3A4>存在");
}
this.HttpContext.Session.Remove(ResetPasswordModel.Key);
return RedirectTo(nameof(ForgotPassword), rawMesage: "请é‡<C3A9>试");
}
[AllowAnonymous]
public JsonResult HasUser([Required] string userName)
{
if (ModelState.IsValid)
{
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == userName);
if (user != null)
{
var list = new List<SelectListItem>();
if (user.EmailConfirmed)
{
list.Add(new SelectListItem { Text = Regex.Replace(user.Email, "...@", "***@"), Value = Url.Action(nameof(SendCodeToEmailForResetPassword)) });
}
var smsEnabled = Convert.ToBoolean(this._settingService.GetSetting("sms").Value);
if (smsEnabled && user.PhoneNumberConfirmed)
{
list.Add(new SelectListItem { Text = Regex.Replace(user.PhoneNumber, "...$", "***"), Value = Url.Action(nameof(SendCodeToPhoneNumberForResetPassword)) });
}
var selectList = new SelectList(list, "Value", "Text");
HttpContext.Response.Headers.Add("x-model", JsonConvert.SerializeObject(selectList));
HttpContext.Session.Set(ResetPasswordModel.Key, new ResetPasswordModel { UserName = userName });
HttpContext.Session.Remove(CodeCaptchaModel.Key);
return Json(true);
}
return Json("用户å<C2B7><C3A5>ä¸<C3A4>存在");
}
return Json("用户å<C2B7><C3A5>ä¸<C3A4>能为空");
}
[AllowAnonymous]
public JsonResult SendCodeToEmailForResetPassword()
{
var model = HttpContext.Session.Get<ResetPasswordModel>(ResetPasswordModel.Key);
if (model != null)
{
try
{
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == model.UserName);
var email = user.Email;
string code = this.GetRandomCode();
this.SendCodeToEmail(email, code);
var seconds = this.GetCaptchaSeconds();
this.HttpContext.Session.Set(CodeCaptchaModel.Key, new CodeCaptchaModel
{
ExpireDateUtc = DateTime.UtcNow.AddSeconds(seconds),
MaxErrorLimit = 5,
Captcha = code
});
return Json(new { success = true, data = seconds });
}
catch (Exception ex)
{
ex.PrintStack();
return Json(new { success = false, data = ex.Message });
}
}
return Json(new { success = false, data = "会è¯<C3A8>已过期,请刷æ°é¡µé<C2B5>¢" });
}
[AllowAnonymous]
public JsonResult SendCodeToPhoneNumberForResetPassword()
{
var model = HttpContext.Session.Get<ResetPasswordModel>(ResetPasswordModel.Key);
if (model == null)
{
try
{
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == model.UserName);
var phoneNumber = user.PhoneNumber;
this._smsSender.Send(phoneNumber, out string code);
var seconds = this.GetCaptchaSeconds();
this.HttpContext.Session.Set(CodeCaptchaModel.Key, new CodeCaptchaModel
{
ExpireDateUtc = DateTime.UtcNow.AddSeconds(seconds),
MaxErrorLimit = 5,
Captcha = code
});
return Json(new { success = true, data = seconds });
}
catch (Exception ex)
{
ex.PrintStack();
return Json(new { success = false, data = ex.Message });
}
}
return Json(new { success = false, data = "会è¯<C3A8>已过期,请刷æ°é¡µé<C2B5>¢" });
}
#endregion é‡<C3A9>设密ç <C3A7>
#region 修改密ç <C3A7>
public IActionResult ChangePassword()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
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: "密ç <C3A7>修改æˆ<C3A6>功");
}
else
{
ModelState.AddModelError(nameof(model.OldPassword), "当å‰<C3A5>密ç <C3A7>输入错误");
}
}
catch (DbUpdateException ex)
{
ex.PrintStack();
ModelState.AddModelError("", ex.Message);
}
}
return View(model);
}
#endregion 修改密ç <C3A7>
#region 用户信æ<C2A1>¯
public IActionResult UserInfo()
{
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == User.Identity.Name);
var model = user.To<EditUserInfoModel>();
return View(model);
}
[HttpPost]
public IActionResult UserInfo(EditUserInfoModel model)
{
try
{
var usreName = User.Identity.Name;
var user = this._userRepo.Table().FirstOrDefault(o => o.UserName == usreName);
user.From(model);
this._userRepo.SaveChanges();
return RedirectTo(rawMesage: "基本信æ<C2A1>¯ä¿®æ”¹æˆ<C3A6>功");
}
catch (Exception ex)
{
ex.PrintStack();
ModelState.AddModelError("", ex.Message);
}
return View(model);
}
#endregion 用户信æ<C2A1>¯
#region 账户安全
public IActionResult Security()
{
return View(this._userRepo.Table().FirstOrDefault(o => o.UserName == User.Identity.Name));
}
#endregion 账户安全
#region 设置修改邮箱
public IActionResult SetEmail()
{
var userName = User.Identity.Name;
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == userName);
return Validate(user);
}
[HttpPost]
public IActionResult SetEmail(ValidateModel model)
{
if (ModelState.IsValid)
{
ModelState.Clear();
ViewData["HtmlAction"] = Url.Action("SetEmail2");
return View();
}
return RedirectTo("ChangeEmail", rawMesage: "请é‡<C3A9>试");
}
[HttpPost]
public IActionResult SetEmail2(ChangeEmailModel model)
{
if (ModelState.IsValid)
{
var userName = User.Identity.Name;
var user = this._userRepo.Table().FirstOrDefault(o => o.UserName == userName);
user.Email = model.Email;
user.EmailConfirmed = true;
this._userRepo.SaveChanges();
return RedirectTo("Security", rawMesage: "设置é®ç®±æˆ<C3A6>功");
}
return RedirectTo("ChangeEmail", rawMesage: "请é‡<C3A9>试");
}
public IActionResult ChangeEmail()
{
var userName = User.Identity.Name;
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == userName);
if (!user.EmailConfirmed)
{
return RedirectTo("SetEmail", rawMesage: "尚未设置邮箱");
}
return Validate(user);
}
[HttpPost]
public IActionResult ChangeEmail(ValidateModel model)
{
if (ModelState.IsValid)
{
ModelState.Clear();
ViewData["HtmlAction"] = Url.Action("ChangeEmail2");
return View();
}
return RedirectTo("ChangeEmail", rawMesage: "请é‡<C3A9>试");
}
[HttpPost]
public IActionResult ChangeEmail2(ChangeEmailModel model)
{
if (ModelState.IsValid)
{
var userName = User.Identity.Name;
var user = this._userRepo.Table().FirstOrDefault(o => o.UserName == userName);
user.Email = model.Email;
this._userRepo.SaveChanges();
return RedirectTo("Security", rawMesage: ´æ<C2B4>¢é®ç®±æˆ<C3A6>功");
}
return RedirectTo("ChangeEmail", rawMesage: "请é‡<C3A9>试");
}
#endregion 设置修改邮箱
#region è®¾ç½®ä¿®æ”¹æ‰æœºå<C2BA>·
public IActionResult SetPhoneNumber()
{
var userName = User.Identity.Name;
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == userName);
return Validate(user);
}
[HttpPost]
public IActionResult SetPhoneNumber(ValidateModel model)
{
if (ModelState.IsValid)
{
ModelState.Clear();
ViewData["HtmlAction"] = Url.Action("SetPhoneNumber2");
return View();
}
return RedirectTo("ChangePhoneNumber", rawMesage: "请é‡<C3A9>试");
}
[HttpPost]
public IActionResult SetPhoneNumber2(ChangePhoneNumberModel model)
{
if (ModelState.IsValid)
{
var userName = User.Identity.Name;
var user = this._userRepo.Table().FirstOrDefault(o => o.UserName == userName);
user.PhoneNumber = model.PhoneNumber;
user.PhoneNumberConfirmed = true;
this._userRepo.SaveChanges();
return RedirectTo("Security", rawMesage: "è®¾ç½®æ‰æœºå<C2BA>·æˆ<C3A6>功");
}
return RedirectTo("ChangePhoneNumber", rawMesage: "请é‡<C3A9>试");
}
public IActionResult ChangePhoneNumber()
{
var userName = User.Identity.Name;
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == userName);
if (!user.PhoneNumberConfirmed)
{
return RedirectTo("SetPhoneNumber", rawMesage: "å°šæœªè®¾ç½®æ‰æœºå<C2BA>·");
}
return Validate(user);
}
[HttpPost]
public IActionResult ChangePhoneNumber(ValidateModel model)
{
if (ModelState.IsValid)
{
ModelState.Clear();
ViewData["HtmlAction"] = Url.Action("ChangePhoneNumber2");
return View();
}
return RedirectTo("ChangePhoneNumber", rawMesage: "请é‡<C3A9>试");
}
[HttpPost]
public IActionResult ChangePhoneNumber2(ChangePhoneNumberModel model)
{
if (ModelState.IsValid)
{
var userName = User.Identity.Name;
var user = this._userRepo.Table().FirstOrDefault(o => o.UserName == userName);
user.PhoneNumber = model.PhoneNumber;
this._userRepo.SaveChanges();
return RedirectTo("Security", rawMesage: ´æ<C2B4>¢æ‰æœºå<C2BA>·æˆ<C3A6>功");
}
return RedirectTo("ChangePhoneNumber", rawMesage: "请é‡<C3A9>试");
}
#endregion è®¾ç½®ä¿®æ”¹æ‰æœºå<C2BA>·
#region 安全验è¯<C3A8>
public JsonResult SendCodeToEmailForValid()
{
try
{
var userName = User.Identity.Name;
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == userName);
var email = user.Email;
string code = this.GetRandomCode();
this.SendCodeToEmail(email, code);
var seconds = this.GetCaptchaSeconds();
this.HttpContext.Session.Set(CodeCaptchaModel.Key, new CodeCaptchaModel
{
ExpireDateUtc = DateTime.UtcNow.AddSeconds(seconds),
MaxErrorLimit = 5,
Captcha = code
});
return Json(new { success = true, data = seconds });
}
catch (Exception ex)
{
ex.PrintStack();
return Json(new { success = false, data = ex.Message });
}
}
public JsonResult SendCodeToPhoneNumberForValid()
{
try
{
var userName = User.Identity.Name;
var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == userName);
var phoneNumber = user.PhoneNumber;
this._smsSender.Send(phoneNumber, out string code);
var seconds = this.GetCaptchaSeconds();
this.HttpContext.Session.Set(CodeCaptchaModel.Key, new CodeCaptchaModel
{
ExpireDateUtc = DateTime.UtcNow.AddSeconds(seconds),
MaxErrorLimit = 5,
Captcha = code
});
return Json(new { success = true, data = seconds });
}
catch (Exception ex)
{
ex.PrintStack();
return Json(new { success = false, data = ex.Message });
}
}
private IActionResult Validate(User user)
{
var list = new List<SelectListItem>();
if (user.EmailConfirmed)
{
list.Add(new SelectListItem { Text = Regex.Replace(user.Email, "...@", "***@"), Value = Url.Action(nameof(SendCodeToEmailForValid)) });
}
var smsEnabled = Convert.ToBoolean(this._settingService.GetSetting("sms").Value);
if (smsEnabled && user.PhoneNumberConfirmed)
{
list.Add(new SelectListItem { Text = Regex.Replace(user.PhoneNumber, "...$", "***"), Value = Url.Action(nameof(SendCodeToPhoneNumberForValid)) });
}
var selectList = new SelectList(list, "Value", "Text");
ViewData["TypeSelectList"] = selectList;
return View("Validate");
}
#endregion 安全验è¯<C3A8>
#region æ<>ƒé™<C3A9>ä¸<C3A4>è¶³
[AllowAnonymous]
public IActionResult AccessDenied(string returnUrl)
{
return View(model: returnUrl);
}
#endregion æ<>ƒé™<C3A9>ä¸<C3A4>è¶³
[AllowAnonymous]
public IActionResult ServerValid()
{
return Json(new
{
Name = this._cfg["name"],
Version = this._cfg["version"]
});
}
//[AllowAnonymous]
//[HttpPost]
//public IActionResult FaceLogin(IFormFile face)
//{
// using var stream = face.OpenReadStream();
// using var bitmap = new System.Drawing.Bitmap(stream);
// Console.WriteLine($"face length:{face.Length}");
// var userName = this._frs.FindFace(bitmap);
// if (!string.IsNullOrEmpty(userName))
// {
// var user = this._userRepo.ReadOnlyTable().FirstOrDefault(o => o.UserName == userName);
// if (user != null)
// {
// var list = this._siteRepo.ReadOnlyTable().ToList();
// var result = new
// {
// Code = 0,
// Token = this._jwtHelper.GetToken(new Dictionary<string, object>() { { nameof(user.UserName), user.UserName } })
// };
// return Json(result);
// }
// }
// return Json(new { Code = 1 });
//}
[AllowAnonymous]
public IActionResult HasLogin()
{
Response.Headers["Content-Type"] = "application/javascript";
return Content($"var hasLogin={(User.Identity.IsAuthenticated ? "true" : "false")}");
}
#region tools
private void SendCodeToEmail(string email, string code)
{
var name = this._settingService.GetSetting("name").Value;
this._emailSender.SendMail(name,
this._settingService.GetSetting("email:user").Value, email,
$"{name}注册验è¯<C3A8>ç <C3A7>", $"{name} 验è¯<C3A8>ç <C3A7>:{code}",
this._settingService.GetSetting("email:host").Value,
Convert.ToInt32(this._settingService.GetSetting("email:port").Value),
this._settingService.GetSetting("email:user").Value,
this._settingService.GetSetting("email:password").Value);
}
private string GetRandomCode(int length = 4)
{
var builder = new StringBuilder();
for (int i = 0; i < length; i++)
{
var random = new byte[1];
using var rg = RandomNumberGenerator.Create();
rg.GetBytes(random);
builder.Append(new Random(Convert.ToInt32(random[0])).Next(0, 9));
}
return builder.ToString();
}
private bool RegisterDisabled()
{
return this._cfg.GetValue<bool>("RegisterDisabled");
}
private int GetCaptchaSeconds()
{
return this._cfg.GetValue<int>("CaptchaSeconds");
}
#endregion tools
}
}