簡體   English   中英

在.NET Core MVC中使用Ajax處理會話超時

[英]Handling session timeout with Ajax in .NET Core MVC

我有一個使用基於cookie的身份驗證的常規應用程序。 它是這樣配置的:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication("Login")
            .AddCookie("Login", c => {
                c.ClaimsIssuer = "Myself";
                c.LoginPath = new PathString("/Home/Login");
                c.AccessDeniedPath = new PathString("/Home/Denied");
            }); 
}

這適用於我的常規操作:

[Authorize]
public IActionResult Users()
{
    return View();
}       

但是對於我的ajax請求來說效果不佳:

[Authorize, HttpPost("Api/UpdateUserInfo"), ValidateAntiForgeryToken, Produces("application/json")]
public IActionResult UpdateUserInfo([FromBody] Request<User> request)
{
    Response<User> response = request.DoWhatYouNeed();

    return Json(response);
}

問題是,當會話到期時,MVC引擎會將操作重定向到登錄頁面,而我的ajax調用將收到該消息。 我希望它返回401的狀態代碼,這樣當它是ajax請求時,我可以將用戶重定向回登錄頁面。 我嘗試編寫策略,但是無法弄清楚如何取消設置或使其忽略從身份驗證服務到登錄頁面的默認重定向。

public class AuthorizeAjax : AuthorizationHandler<AuthorizeAjax>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AuthorizeAjax requirement)
    {
        if (context.User.Identity.IsAuthenticated)
        {
            context.Succeed(requirement);
        }
        else
        {   
            context.Fail();
            if (context.Resource is AuthorizationFilterContext redirectContext)
            {
                // - This is null already, and the redirect to login will still happen after this.
                redirectContext.Result = null;
            }
        }

        return Task.CompletedTask;
    }
}

我怎樣才能做到這一點?

編輯:經過大量的搜索之后,我在2.0版中發現了這種處理它的新方法:

services.AddAuthentication("Login")
        .AddCookie("Login", c => {
                   c.ClaimsIssuer = "Myself";
                   c.LoginPath = new PathString("/Home/Login");
                   c.Events.OnRedirectToLogin = (context) =>
                   {
                       // - Or a better way to detect it's an ajax request
                       if (context.Request.Headers["Content-Type"] == "application/json")
                       {
                           context.HttpContext.Response.StatusCode = 401;
                       }
                       else
                       {
                           context.Response.Redirect(context.RedirectUri);
                       }

                       return Task.CompletedTask;
                   };                       
        });

現在就可以使用!

您可以通過擴展AuthorizeAttribute類來實現。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AjaxAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
             filterContext.HttpContext.Response.StatusCode = 401;
             filterContext.Result = new JsonResult
             {
                 Data = new { Success = false, Data = "Unauthorized" },
                 ContentEncoding = System.Text.Encoding.UTF8,
                 ContentType = "application/json",
                 JsonRequestBehavior = JsonRequestBehavior.AllowGet
             };
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

然后,您可以在Ajax方法上指定此屬性。

希望這可以幫助。

參考: http : //benedict-chan.github.io/blog/2014/02/11/asp-dot-net-mvc-how-to-handle-unauthorized-response-in-json-for-your-api/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM