Expressjs将用户重定向到/ logout,API调用出现401错误

时间:2017-12-28 02:47:17

标签: node.js express xmlhttprequest

当我在API调用(AJAX调用)上遇到401错误时,我有一个用例将用户重定向到登录页面。我已将快速中间件定义如下,注销用户并重定向到登录页面。

//logout route
app.get('/logout', function(req, res) {
    req.session.destroy();
    req.logout();
    passportConfig.reset(); //reset auth tokens
    res.redirect(config.uaaURL + '/logout?redirect=' + config.appURL);
});

我使用passportjs和connect-redis在会话中存储用户令牌和客户端令牌并进行身份验证。用户令牌用于浏览器上的用户会话,客户端令牌用于服务调用。当用户令牌过期时,我可以将用户重定向到登录页面。这是我面临的挑战,我编写了一个XMLHttpRequest拦截器,如下所示,将服务调用(AJAX调用)上的错误重定向到/ logout路由。我看到它正在进行/注销,但是在页面中看到未经授权,经过一段时间我点击同一个网址后,它会将我重定向到登录页面。

XMLHttpRequest拦截器代码段:

// Self contain and executed analymous function
(function() {
    var send = XMLHttpRequest.prototype.send;
    var setRequestHeader = XMLHttpRequest.prototype.setRequestHeader;

    XMLHttpRequest.prototype.send = function(data) {
        var self = this;
        var oldOnReadyStateChange;

        function returnResponseToApp() {
            // continue to return data
            if (oldOnReadyStateChange) {
                oldOnReadyStateChange.call(self);
            }
        }

        // save old ready state change
        oldOnReadyStateChange = this.onreadystatechange;
        this.onreadystatechange = function() {
            var response;

            if (self.readyState === 4 /* complete */) {
                // get x-csrf-token header

                if (self.status === 401 || self.status === 403) {
                    console.log('Resp status >>'+self.status);
                    /**
                     * when status is 403 access denied
                     * The app will redirect user to access denied page
                     */
                    if (self.status === 403) {
                        returnResponseToApp();
                    } else {
                        // when status is 401 not authenticated
                        try {
                            /**
                             * special case when user require to change password
                             * check the response description by converting response to JSON object
                             */
                            response = JSON.parse(self.response);
                            if (response.error_description === 'password_change_required') { // jshint ignore:line
                                returnResponseToApp();
                            } else {
                                // in all case when 401 is returned logout the user
                                this.redirectToLogout();
                            }
                        } catch (e) {
                            // in all case when 401 is returned logout the user
                            this.redirectToLogout();
                        }
                    }
                } else {
                    returnResponseToApp();
                }
            }
        };


        this.redirectToLogout = function() {
            window.location.replace('/logout');
            this.abort();
        }.bind(this);

        send.call(this, data);
    };
})();

我看到的行为是:

enter image description here

0 个答案:

没有答案