AngularJS应该如何处理$http.post中由于过期的XSRF令牌而出现的403错误?

unftdfkk  于 2023-08-02  发布在  Angular
关注(0)|答案(2)|浏览(138)

AngularJS版本1.4.8应用程序在用户浏览器打开了许多小时(本例中为16小时)后,其登录表单将数据发送到后端REST身份验证服务时,会收到一个未处理的403错误。经过深入分析,根本原因是客户端AngularJS应用程序的XSRF-TOKENJSESSIONID的过期cookie,这导致后端Spring Security拒绝了对公共/login1服务的请求,因为Spring认为请求是跨站点请求伪造。
如果用户关闭所有浏览器窗口,然后在再次发出请求之前重新打开新的浏览器窗口,则可以手动解决该问题。但这不是一个可接受的用户体验。我已经读过the AngularJS documentation at this link,我看到我可以添加一个errorCallback函数,但是我应该如何重写这个函数来处理403错误?
下面是授权服务中的原始this.logForm()方法,您可以看到它不处理403错误:

this.logForm = function(isValid) {
    if (isValid) {
        var usercredentials = {type:"resultmessage", name: this.credentials.username, encpwd: this.credentials.password };
        $http.post('/login1', usercredentials)
            .then(
                function(response, $cookies) {              
                    if(response.data.content=='login1success'){// do some stuff
                    } else {// do other stuff
                    }
                }
            );
    }
};

字符串
下面是我对this.logForm()方法的一个非常粗略的尝试,它试图处理403错误,下面是AngularJS文档中的示例:

this.logForm = function(isValid) {
    if (isValid) {
        var usercredentials = {type:"resultmessage", name: this.credentials.username, encpwd: this.credentials.password };
        $http({ method: 'POST', url: '/login1', usercredentials })
            .then(
                function successCallback(response, $cookies) {
                    // this callback will be called asynchronously when the response is available
                    if(response.data.content=='login1success'){// do some stuff
                    } else {// do other stuff
                    }
                }, 
                function errorCallback(response, status) {// is status a valid parameter to place here to get the error code?
                    // called asynchronously if an error occurs or server returns response with an error status.
                    if(status == 403){
                        this.clearCookies();
                        // try to call this POST method again, but how?  And how avoid infinite loop?
                    }
                }
            );
        }
    };

需要对上面的代码进行哪些具体的更改来处理由于服务器感知的XSRF-TOKEN和JSESSIONID问题而导致的403错误?在删除cookie不能解决403错误的情况下,如何在删除cookie后再次调用帖子而不导致无限循环?

我也在研究错误处理的全局方法,但公共和安全后端REST服务的组合,需要单独处理,导致复杂性。这个登录表单是用户输入的第一个点,我希望在查看全局方法之前单独处理它,这些方法将保留使用响应此OP开发的方法单独处理登录表单。

imzjd6km

imzjd6km1#

您可以将HTTP调用重新构造为自动重试,并在控制器中使用Promise(或其他)

var httpPostRetry = function(url, usercredentials) {
    var promise = new Promise(function(resolve, reject) {

    var retries = 0;
    var postRetry = function(url, usercredentials) {
      if (retries < 3) {
       $http({ method: 'POST', url: '/login1', usercredentials })
        .then(function(result) {
          resolve(result);
        }).catch(function(result) {
          retries ++;
          postRetry(url, usercredentials);
        });
      } else {
        reject(result);
      }
    };

  }.bind(this));
  return promise;
}

字符串
然后你会打电话给

httpPostRetry(bla, bla).then(function(result) {
  // one of the 3 tries must of succeeded
}).catch(function(result) {
  // tried 3 times and failed each time
});


要处理特定的http错误,您可以广播该特定的错误,并在特定的控制器中处理该情况。或者使用服务封装状态,并让代码的其他部分处理该错误的UI流。

$rootScope.$broadcast('unauthorized http error', { somedata: {} });


这样有用吗

rdlzhqv9

rdlzhqv92#

看看angular-http-auth module和事情是如何完成的。我认为你会想要使用的一个关键元素是http拦截器。
出于全局错误处理、认证或请求的任何种类的同步或异步预处理或响应的后处理的目的,期望能够在请求被移交给服务器之前拦截请求,并且在响应被移交给发起这些请求的应用代码之前拦截响应。拦截器利用promise API来满足同步和异步预处理的需求。
在尝试了一下拦截器之后,您可以看看angular-http-auth http缓冲区以及它们处理被拒绝请求的方式。如果他们的拦截器收到一个responseError,他们将config对象(基本上存储了所有请求的信息)添加到缓冲区,然后他们可以随时操纵缓冲区中的元素。当收到403时,您可以很容易地熟练他们的代码来操作配置的xsrfHeaderName、xsrfCookieName或参数。

相关问题