using Hangfire; using Masuit.MyBlogs.Core.Common; using Masuit.MyBlogs.Core.Configs; using Masuit.MyBlogs.Core.Extensions; using Masuit.MyBlogs.Core.Infrastructure.Services; using Masuit.MyBlogs.Core.Models.Enum; using Masuit.Tools; using Masuit.Tools.Logging; using Masuit.Tools.Security; using Masuit.Tools.Systems; using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System; using System.Web; namespace Masuit.MyBlogs.Core.Controllers { /// /// 错误页 /// [ApiExplorerSettings(IgnoreApi = true)] public class ErrorController : Controller { public BroadcastService BroadcastService { get; set; } /// /// 404 /// /// [Route("error"), Route("{*url}", Order = 99999), ResponseCache(Duration = 36000)] public ActionResult Index() { if (Request.Method.ToLower().Equals("get")) { Response.StatusCode = 404; return View(); } return Json(new { StatusCode = 404, Success = false, Message = "页面未找到!" }); } /// /// 503 /// /// [Route("ServiceUnavailable")] public ActionResult ServiceUnavailable() { var feature = HttpContext.Features.Get(); if (feature != null) { string err; var req = HttpContext.Request; var ip = HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString(); switch (feature.Error) { case DbUpdateConcurrencyException ex: err = $"异常源:{ex.Source},异常类型:{ex.GetType().Name},\n请求路径:{req.Scheme}://{req.Host}{HttpUtility.UrlDecode(req.Path)},客户端用户代理:{req.Headers["User-Agent"]},客户端IP:{ip}\t{ex.InnerException?.Message}\t"; LogManager.Error(err, ex); break; case DbUpdateException ex: err = $"异常源:{ex.Source},异常类型:{ex.GetType().Name},\n请求路径:{req.Scheme}://{req.Host}{HttpUtility.UrlDecode(req.Path)},客户端用户代理:{req.Headers["User-Agent"]},客户端IP:{ip}\t{ex?.InnerException?.Message}\t"; LogManager.Error(err, ex); break; case AggregateException ex: LogManager.Debug("↓↓↓" + ex.Message + "↓↓↓"); ex.Handle(e => { LogManager.Error($"异常源:{e.Source},异常类型:{e.GetType().Name},\n请求路径:{req.Scheme}://{req.Host}{HttpUtility.UrlDecode(req.Path)},客户端用户代理:{req.Headers["User-Agent"]},客户端IP:{ip}\t", e); return true; }); break; case NotFoundException ex: Response.StatusCode = 404; return Request.Method.ToLower().Equals("get") ? (ActionResult)View("Index") : Json(new { StatusCode = 404, Success = false, ex.Message }); default: LogManager.Error($"异常源:{feature.Error.Source},异常类型:{feature.Error.GetType().Name},\n请求路径:{req.Scheme}://{req.Host}{HttpUtility.UrlDecode(req.Path)},客户端用户代理:{req.Headers["User-Agent"]},客户端IP:{ip}\t", feature.Error); break; } } if (Request.Method.ToLower().Equals("get")) { Response.StatusCode = 503; return View(); } return Json(new { StatusCode = 503, Success = false, Message = "服务器发生错误!" }); } /// /// 访问被拒绝 /// /// [Route("AccessDeny"), ResponseCache(Duration = 360000)] public ActionResult AccessDeny() { if (Request.Cookies["Email"].MDString3(AppConfig.BaiduAK).Equals(Request.Cookies["FullAccessToken"])) { return Redirect("/"); } Response.StatusCode = 403; return View(); } /// /// 临时被拒绝 /// /// [Route("TempDeny"), ResponseCache(Duration = 360000)] public ActionResult TempDeny() { Response.StatusCode = 403; return View(); } /// /// 网站升级中 /// /// [Route("ComingSoon"), ResponseCache(Duration = 360000)] public ActionResult ComingSoon() { return View(); } /// /// 检查访问密码 /// /// /// /// [HttpPost, ValidateAntiForgeryToken, AllowAccessFirewall, ResponseCache(Duration = 115, VaryByQueryKeys = new[] { "email", "token" })] public ActionResult CheckViewToken(string email, string token) { if (string.IsNullOrEmpty(token)) { return ResultData(null, false, "请输入访问密码!"); } var s = RedisHelper.Get("token:" + email); if (!token.Equals(s)) { return ResultData(null, false, "访问密码不正确!"); } Response.Cookies.Append("Email", email, new CookieOptions { Expires = DateTime.Now.AddYears(1) }); Response.Cookies.Append("FullAccessToken", email.MDString3(AppConfig.BaiduAK), new CookieOptions { Expires = DateTime.Now.AddYears(1) }); return ResultData(null); } /// /// 检查授权邮箱 /// /// /// [HttpPost, ValidateAntiForgeryToken, AllowAccessFirewall, ResponseCache(Duration = 115, VaryByQueryKeys = new[] { "email" })] public ActionResult GetViewToken(string email) { if (string.IsNullOrEmpty(email) || !email.MatchEmail()) { return ResultData(null, false, "请输入正确的邮箱!"); } if (RedisHelper.Exists("get:" + email)) { RedisHelper.Expire("get:" + email, 120); return ResultData(null, false, "发送频率限制,请在2分钟后重新尝试发送邮件!请检查你的邮件,若未收到,请检查你的邮箱地址或邮件垃圾箱!"); } if (!BroadcastService.Any(b => b.Email.Equals(email) && b.SubscribeType == SubscribeType.ArticleToken)) { return ResultData(null, false, "您目前没有权限访问这个链接,请联系站长开通访问权限!"); } var token = SnowFlake.GetInstance().GetUniqueShortId(6); RedisHelper.Set("token:" + email, token, 86400); BackgroundJob.Enqueue(() => CommonHelper.SendMail(CommonHelper.SystemSettings["Domain"] + "博客访问验证码", $"{CommonHelper.SystemSettings["Domain"]}本次验证码是:{token},有效期为24h,请按时使用!", email)); RedisHelper.Set("get:" + email, token, 120); return ResultData(null); } /// /// 响应数据 /// /// 数据 /// 响应状态 /// 响应消息 /// public ActionResult ResultData(object data, bool success = true, string message = "") { return Ok(new { Success = success, Message = message, Data = data }); } } }