在自定义授权期间强制ajax .fail()来管理登录重定向

Force ajax .fail() during custom authorization to manage login redirect

本文关键字:管理 重定向 登录 fail ajax 授权 自定义      更新时间:2023-09-26

在MVC应用程序中,我有一个jQuery ajax post到控制器中的方法:

function initFormForInsert(metodoLoadForm, nomeForm, divForm, widthForm, heightForm, metodoInsert) {
    blockPage();
    var request = $.ajax(
        {
            type: 'POST',
            url: getRootURL() + metodoLoadForm
        });
    request.done(function (data) {
    //alert(data);
    LoadFormForInsert(data, nomeForm, divForm, widthForm, heightForm, metodoInsert);
});
request.fail(function (jqXHR, textStatus) {
        unblockPage();
        showErrorDialog("Error", textStatus);
    });
}

我可以用某种方式强制request.fail()吗?

因为我在控制器中使用全局过滤器对所有方法进行授权(代码如下)特别是当我收到这个Ajax帖子和我的会话变量为空时,我想抛出一个异常。

protected override bool AuthorizeCore(HttpContextBase httpContext) {
    try {
        UserToken cUt = httpContext.GetUser();
        if (cUt == null) {
            //session is null
            return false;
        }
        string request = httpContext.Request.Path;
        if (httpContext.Request.Path.LastOrDefault() == '/')
            request = httpContext.Request.Path.Remove(httpContext.Request.Path.Length - 1);
        if (cUt.DeniedActions.Contains(request.ToUpper())) {
            //user is not authorized
            return false;
        }
        return true;
    } catch (Exception) {
        return false;
    }
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
    UserToken cUt = filterContext.HttpContext.GetUser();
    if (cUt == null) {
        //session is null
        if (
            //filterContext.HttpContext.Response.StatusCode == 302 &&
            filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest"
        ) {
            //filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = 401;
        } else {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary(
                    new {
                        controller = "Login",
                        action = "Login"
                    })
            );
        }
    } 

我这样修改了JavaScript对话框:

function initFormForInsert(metodoLoadForm, nomeForm, divForm, widthForm, heightForm, metodoInsert) {
    blockPage();
    var request = $.ajax(
            {
                type: 'POST',
                url: getRootURL() + metodoLoadForm,
                statusCode: { 
                    200: function (data) {
                        //alert(200);
                   LoadFormForInsert(data, nomeForm, divForm, widthForm, heightForm, metodoInsert);
                    }, 
                    401: function (jqXHR, textStatus, errorThrown) {
                        //alert(401);
                    hrefTo("/Login/Login") ;
                } 
               } 
            });
    //request.done(function (data) {
    //    //alert(data);
    //    LoadFormForInsert(data, nomeForm, divForm, widthForm, heightForm, metodoInsert);
    //});
    request.fail(function (jqXHR, textStatus) {
        unblockPage();
        showErrorDialog("Errore inizializzando la form per inserimento ", textStatus);
    });
}

和这样的授权:

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    try
    {        
        UserToken cUt = httpContext.GetUser();
        if (cUt == null)
            //session is null
        {
            return false;
        }
        string request = httpContext.Request.Path;
        if (httpContext.Request.Path.LastOrDefault() == '/')
            request = httpContext.Request.Path.Remove(httpContext.Request.Path.Length - 1);
        if (cUt.DeniedActions.Contains(request.ToUpper()))
        {
            //user is not authorized
            return false;
        }
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    UserToken cUt = filterContext.HttpContext.GetUser();
    if (cUt == null)
    {
        // session is null                
        if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
        {
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            filterContext.HttpContext.Response.End();
            return;
        }
        else
        {
            filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary(
                        new
                        {
                            controller = "Login",
                            action = "Login"
                        })
                    );
        }
    }
}

你觉得可以吗?

或者其他方法,即使速度较慢,也可以在if分支中添加对会话变量

的检查
   blockPage();
    if (checkSessionVariable()) {
        hrefTo("/Login/Login");
    }
    else {
        var request = $.ajax(
                {
                    type: 'POST',
                    url: getRootURL() + metodoLoadForm,

                });
        request.done(function (data) {
            //alert(data);
            LoadFormForInsert(data, nomeForm, divForm, widthForm, heightForm, metodoInsert);
        });
        request.fail(function (jqXHR, textStatus) {
            unblockPage();
            showErrorDialog("Errore inizializzando la form per inserimento ", textStatus);
        });
    }

其中check session variable是另一个检查session变量的post

function checkSessionVariable() {
    var request = $.ajax(
    {
        type: 'POST',
        url: getRootURL() + "/Login/SessionExpired"
    });
    request.done(function (data) {
        return (data);
    });
    request.fail(function (jqXHR, textStatus) {
        return 0;
    });
}

也许这是一个更可靠的解决方案?

不建议提供500或403错误作为解决方案。请记住,这些是状态码,表示N/w失败,资源未找到

相反,尝试将来自服务器的结果作为负面场景的正面响应来处理这意味着现在需要按如下方式处理数据

request.done(function (data) {
        //alert(data);
        if(data.positive) {
LoadFormForInsert(data, nomeForm, divForm, widthForm, heightForm, metodoInsert);
}
 else if(data.negative){
unblockPage();
        showErrorDialog("Error", textStatus);
}
    });

你也可以传递cookie,例如(下面的伪代码)

request.done(function (data) {
            //alert(data);
            if(cookie == "positive") {
    LoadFormForInsert(data, nomeForm, divForm, widthForm, heightForm, metodoInsert);
    }
     else if(cookie == "negative"){
    unblockPage();
            showErrorDialog("Error", textStatus);
    }
        });