如何在Backbone中处理服务器的注销确认请求

flvlnr44  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(170)

我有一个项目,包括一个servlet/restlet后端(用Java8框架编写)和Backbone前端。
Backbone有一个“注销”按钮,用于终止用户与服务器的浏览器会话,并将其返回到应用程序的登录提示符。
Java框架的原始版本包括一个Web服务器,该服务器没有发出确认注销的请求。因此, Backbone.js 代码工作得很好。Chrome DevTools显示的网络通话记录如下:
x1c 0d1x的数据
Java框架现在必须更新到一个更新得多的版本; Backbone.js 代码没有被修改新的Java框架中的Web服务现在请求注销确认,而Backbone没有按需处理:而不是被重定向到登录提示符,应用程序的当前页面(包含注销按钮的页面)只是被重新显示,因此实现注销的唯一方法是关闭浏览器窗口并重新启动后端!Chrome DevTools显示这个新的网络调用日志如下(请忽略与面板相关的第一行):



我是Backbone的新手,没有编写原始代码。我只是想知道如何通过适当地响应logoutConfirm来更改它以使logout再次工作。我采用了原始代码,没有第三方库,然后剥离了任何纯粹与应用程序相关的内容,只留下与授权和注销相关的代码-我希望这是我正在使用的代码的简化复制(见下文)。
顺便说一句,与单击Logout按钮相对应的事件是几乎在代码示例末尾显示的'click .logoutlink'。
有谁能告诉我哪些需要改变,为什么?多谢了。

function AppAuth() {
    return {
        _currentUser: undefined,
        _redirectTo: undefined,

        isAuthorized: function () {
            return app.cookieCutter.get('apphash') !== undefined;
        },

        currentUser: function () {
            return this._currentUser;
        },

        // If user authorised, just return. If not, change the hash to /login
        authorizedOrRedirect: function () {
            if (!app.auth.isAuthorized() && window.location.hash != '/login') {
                app.auth._redirectTo = window.location.hash; // Save current page to go back to
                this.logout();
                return false;
            }
        },

        logout: function () {
            if (this._currentUser != undefined) {
                this._currentUser.trigger('logout');
            }

            this._currentUser = undefined;

            $.ajax("/logout", {
                type: "GET"
            });

            var cookies = app.cookies.keys();
            _.forEach(cookies, function (cookie) {
                app.cookieCutter.remove(cookie);
            });

            window.location.pathname = "/logout";
            return true;
        },
    };
}

app = {};
app.traceUrlEvents = true;

// Comment out if NOT CORS requests. In our case they are until release:
app.apiIsCrossOrigin = true;
jQuery.support.cors = true;

// Remote working
app.apiRoot = '/v1';
app.loginEndpoint = '/login';

// Localhost
app.auth = APPAuth();

if (app._queueSameGetRequests) {
    Backbone.xhrs = {};
    var oldFetch = Backbone.Model.prototype.fetch;
    Backbone.Model.prototype.fetch = function (opts) {
        var self = this;
        var args = arguments;
        // cache GET requests, not the others
        if (!opts || opts['cache'] !== true) {
            return oldFetch.apply(this, arguments);
        }

        var promise;
        var r;

        if (_.isFunction(this.url)) {
            r = this.url();
        } else {
            r = this.url;
        }

        // issue the request if a cached version does not exist
        if (!Backbone.xhrs[r]) {
            promise = Backbone.xhrs[r] = oldFetch.apply(this, arguments);
        } else {
            var p = Backbone.xhrs[r].done(function () {
                oldFetch.apply(self, args);
            });
            return p;
        }
        return promise;
    };
}

// Default error handlers for network and other XHR errors
app.networkAuthErrorHandler = function () {
    app.auth.logout();
    // Refresh the window, this should cause redirection to login screen. Could loop ?
    console.log("302 from API, authorization required");
    app.auth.authorizedOrRedirect();
};

app.networkErrorHandler = function () {
    $('#global-warn').show();
};

// Handle transport errors/network being down
$(document).ajaxError(function (evt, resp, request, txt) {
    if (resp.status === 0) {
        app.networkErrorHandler();
    }
});

app.Router = {};

app.boot = function () {
    app.EventObject = {};
    _.extend(app.EventObject, Backbone.Events);
    new app.controllers.DefaultController();
    app.Router = new app.controllers.Auth();
    new app.controllers.Users();

    // Force authorisation check when using navigate from within app
    var triggerNewRoute = function () {
        console.log("Route change", arguments);
        app.EventObject.trigger('routeChange');
        app.auth.authorizedOrRedirect();
    };

    Backbone.$(window).on('hashchange', triggerNewRoute);

    if (app.traceUrlEvents) {
        Backbone.$(window).on('pushstate', urlTraces);
        Backbone.$(window).on('popstate', urlTraces);
        Backbone.$(window).on('hashchange', urlTraces);
    }
};

app.models.BaseModel = Backbone.Model.extend({
    apiRoot: function () {
        return app.apiRoot;
    },

    // Overwrite to support trailing slashes
    url: function () {
        var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || this.urlError();
        if (this.isNew()) return base;
        return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id) + '/';
    },
});

(function (global) {
    'use strict';
})(this);

app.controllers.Auth = app.controllers.BaseController.extend({
    routes: {
        "auth/": "getAuthPage"
    },

    getAuthPage: function () {
        var loginView = new app.views.LoginView();
        app.rootView.renderMainView(loginView, 'login');

        if (app.auth.isAuthorized()) {
            app.Router.navigate('//', { trigger: true });
        }
    }
});

// Router/controller for the user list page
app.controllers.Users = app.controllers.BaseController.extend({
    "routes": {
        "logout/": "logoutCurrentUser"
    },

    logoutCurrentUser: function () {
        console.log(">>>>> logoutCurrentUser() is empty function !!")
    }
});

// Render the title bar
app.views.Headerbar = Backbone.View.extend({
    template: 'topbar',
    className: 'navbar navbar-main',
    events: {
        'click .logoutlink': 'doLogout',
    },

    doLogout: function (e) {
        e.preventDefault();
        app.auth.logout();
        window.location = app.loginEndpoint;
        return false;
    }
});

字符串

js4nwp54

js4nwp541#

当用户单击注销链接时,将调用app.auth.logout()函数。此函数触发当前用户对象(如果存在)上的'logout'事件,将_currentUser变量设置为undefined,并对“/logout”执行 AJAX GET请求以通知服务器注销操作。
执行logout函数后,调用app.auth.logoutCurrentUser()函数。但是,在提供的代码中,此函数为空,不包含任何特定的逻辑。它似乎是一个占位符函数,可以用所需的服务器端注销确认逻辑进一步实现。
要在Backbone中处理服务器的注销确认请求,您需要执行以下步骤:
实现处理来自客户端的注销请求的服务器端端点或API。此端点应执行必要的操作以确认注销并使用户会话无效。
修改app.controllers.Users控制器中的logoutCurrentUser函数,向服务器的注销端点发送请求。您可以使用$. AJAX 函数或Backbone支持的任何其他方法来发出请求。举例来说:

logoutCurrentUser: function() {
$.ajax({
    url: "/logout/confirmation", // Replace with the appropriate server-side endpoint
    type: "POST", // or "GET" depending on your server implementation
    success: function(response) {
        // Handle the server's confirmation response here
        console.log("Logout confirmed:", response);
        // Perform any additional client-side actions if needed
    },
    error: function(xhr, status, error) {
        // Handle the error case if the server request fails
        console.log("Logout confirmation request failed:", error);
        // Perform any error handling or display appropriate messages
    }
});

字符串
}
自定义服务器端注销端点,以根据应用程序的要求处理注销确认逻辑。这可能涉及使用户的会话无效、更新服务器端状态以及向客户端返回确认响应。

相关问题