在 .NET Core MVC 中使用 Ajax 处理会话超时 [英] Handling session timeout with Ajax in .NET Core MVC

查看:26
本文介绍了在 .NET Core MVC 中使用 Ajax 处理会话超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用基于 cookie 的身份验证的常规应用程序.这是它的配置方式:

I have a regular application using cookie based authentication. This is how it's configured:

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

这适用于我的常规操作:

This works for my regular actions:

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

但对我的 ajax 请求效果不佳:

But doesn't work well for my ajax requests:

[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 请求时将用户重定向回登录页面.我尝试编写策略,但我不知道如何取消设置或使其忽略从身份验证服务到登录页面的默认重定向.

The problem is that when the session expires, the MVC engine will redirect the action to the login page, and my ajax call will receive that. I'd like it to return the status code of 401 so I can redirect the user back to the login page when it's an ajax request. I tried writing a policy, but I can't figure how to unset or make it ignore the default redirect to login page from the authentication service.

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 版中找到了这种处理它的新方法:

After a lot of googling, I found this new way of handling it in version 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 类来实现.

What you need can be achieved by extending AuthorizeAttribute class.

[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 方法上指定此属性.

You can then specify this attribute on Ajax methods.

希望这会有所帮助.

参考:http://benedict-chan.github.io/blog/2014/02/11/asp-dot-net-mvc-how-to-handle-未经授权的响应在 json-for-your-api/

这篇关于在 .NET Core MVC 中使用 Ajax 处理会话超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆