首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在.NET核心MVC中使用Ajax处理会话超时

在.NET核心MVC中使用Ajax处理会话超时
EN

Stack Overflow用户
提问于 2019-03-26 02:52:39
回答 1查看 2.8K关注 0票数 2

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

代码语言:javascript
复制
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");
            }); 
}

这适用于我的常规操作:

代码语言:javascript
复制
[Authorize]
public IActionResult Users()
{
    return View();
}       

但是对于我的ajax请求不能很好地工作:

代码语言:javascript
复制
[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请求时,我可以将用户重定向回登录页面。我尝试编写一个策略,但我不知道如何取消设置或使其忽略来自身份验证服务的默认重定向到登录页面。

代码语言:javascript
复制
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版本中发现了这种新的处理方式:

代码语言:javascript
复制
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;
                   };                       
        });

现在它就能工作了!

EN

回答 1

Stack Overflow用户

发布于 2019-03-26 03:47:18

您需要的内容可以通过扩展AuthorizeAttribute类来实现。

代码语言:javascript
复制
[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/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55344665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档