LoginRequiredMiddleware.cs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using Common.Extension;
  2. namespace Kitty_Fall.Website.Helpers;
  3. public class LoginRequiredMiddleware
  4. {
  5. private readonly RequestDelegate _next;
  6. public LoginRequiredMiddleware(RequestDelegate next)
  7. {
  8. _next = next;
  9. }
  10. public async Task InvokeAsync(HttpContext context)
  11. {
  12. if (ShouldSkip(context))
  13. {
  14. await _next(context);
  15. return;
  16. }
  17. var msisdn = context.Session.GetComplexData<string>("msisdn");
  18. if (!string.IsNullOrWhiteSpace(msisdn))
  19. {
  20. await _next(context);
  21. return;
  22. }
  23. context.Response.Headers.CacheControl = "no-store";
  24. if (IsAjaxRequest(context.Request))
  25. {
  26. // Ajax: quay lại trang đang đứng (Referer) sau khi đăng nhập trên trình duyệt.
  27. var redirectUrl = AccessChannelHelper.GetLoginRedirectUrl(context, GetLocalReferer(context.Request));
  28. context.Response.StatusCode = StatusCodes.Status401Unauthorized;
  29. context.Response.Headers["X-Login-Required"] = "true";
  30. context.Response.Headers["X-Login-Redirect"] = redirectUrl;
  31. await context.Response.WriteAsJsonAsync(new
  32. {
  33. success = false,
  34. errorCode = Common.CommonErrorCode.LoginRequired,
  35. redirectUrl
  36. });
  37. return;
  38. }
  39. var returnUrl = context.Request.Method == HttpMethods.Get
  40. ? $"{context.Request.PathBase}{context.Request.Path}{context.Request.QueryString}"
  41. : null;
  42. context.Response.Redirect(AccessChannelHelper.GetLoginRedirectUrl(context, returnUrl));
  43. }
  44. private static bool ShouldSkip(HttpContext context)
  45. {
  46. var path = context.Request.Path;
  47. if (path.StartsWithSegments("/Login")) return true;
  48. if (path.StartsWithSegments("/Home/ChangeLanguage")) return true;
  49. if (path.StartsWithSegments("/favicon.ico")) return true;
  50. if (path.StartsWithSegments("/kitty")) return true;
  51. if (path.StartsWithSegments("/css")) return true;
  52. if (path.StartsWithSegments("/js")) return true;
  53. if (path.StartsWithSegments("/lib")) return true;
  54. if (path.StartsWithSegments("/assets")) return true;
  55. return false;
  56. }
  57. private static string? GetLocalReferer(HttpRequest request)
  58. {
  59. var referer = request.Headers.Referer.ToString();
  60. if (string.IsNullOrWhiteSpace(referer)
  61. || !Uri.TryCreate(referer, UriKind.Absolute, out var uri)
  62. || !string.Equals(uri.Host, request.Host.Host, StringComparison.OrdinalIgnoreCase))
  63. {
  64. return null;
  65. }
  66. return uri.PathAndQuery;
  67. }
  68. private static bool IsAjaxRequest(HttpRequest request)
  69. {
  70. return string.Equals(request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.OrdinalIgnoreCase)
  71. || string.Equals(request.Headers["Sec-Fetch-Dest"], "empty", StringComparison.OrdinalIgnoreCase)
  72. || request.Headers.Accept.Any(x => x?.Contains("application/json", StringComparison.OrdinalIgnoreCase) == true);
  73. }
  74. }