javascript Expressjs 不会破坏会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11575807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 13:43:00  来源:igfitidea点击:

Expressjs doesn't destroy session

javascriptnode.jssessionexpress

提问by bodokaiser

I have an Backbone View which sends an Ajax call to the server to remove a session.

我有一个 Backbone 视图,它向服务器发送 Ajax 调用以删除会话。

On the server following event is triggered:

在服务器上触发以下事件:

app.delete('/session', function(req, res) {
    if (req.session) {
        req.session.destroy(function() {
            res.clearCookie('connect.sid', { path: '/' });
            res.send('removed session', 200);
        });
    } else {
        res.send('no session assigned', 500);
    }
});

The weird about this is that I can press the logout button multiple times without getting a HTTP 500 error code. Also chromium shows me that a cookie still exists.

奇怪的是,我可以多次按下注销按钮而不会收到 HTTP 500 错误代码。铬还告诉我cookie仍然存在。

What is going wrong?

出了什么问题?

Regards

问候

EDIT:

编辑

I found out that this isn't directly a session issue but a cookie one. I added res.clearCookie to the route. Unfortunatly the behaviour (cookie, session keep alive) didn't change

我发现这不是直接的会话问题,而是 cookie 问题。我将 res.clearCookie 添加到路由中。不幸的是行为(cookie,会话保持活动)没有改变

EDIT2: I now gave res.clearCookie some parameters => res.clearCookie('connect.sid', { path: '/' }); Now at least the cookie is gone in the browser. But the session seems to be still available. Or at least I can call the logout route how often I want even req.session should be false

EDIT2:我现在给 res.clearCookie 一些参数 => res.clearCookie('connect.sid', { path: '/' }); 现在至少 cookie 在浏览器中消失了。但是会话似乎仍然可用。或者至少我可以调用注销路由的频率我希望 req.session 应该是假的

EDIT3:I now removed all sessions out of redis and restarted everything (redis, node, browser). Than I have logged in again and logged out. This works so far but when I relaod the page with F5 I get a new session. WHY?

EDIT3:我现在从 redis 中删除了所有会话并重新启动了所有内容(redis、节点、浏览器)。比我再次登录并注销。到目前为止,这有效,但是当我使用 F5 重新加载页面时,我得到了一个新会话。为什么?

采纳答案by bodokaiser

To concentrate all comments together I have written an answer:

为了将所有评论集中在一起,我写了一个答案:

Because express always creates a session and a cookie for a client we have to take a different approach than just to check if there is a session.

因为 express 总是为客户端创建会话和 cookie,所以我们必须采取不同的方法,而不仅仅是检查是否存在会话。

This parts handles logins

这部分处理登录

app.post('/session', function(req, res) {
    User.findOne({ username: req.body.username })
        .select('salt') // my mongoose schema doesn't fetches salt
        .select('password') // and password by default
        .exec(function(err, user) {
            if (err || user === null) throw err; // awful error handling here
            // mongoose schema methods which checks if the sent credentials
            // are equal to the hashed password (allows callback)
            user.hasEqualPassword(req.body.password, function(hasEqualPassword) {
                if (hasEqualPassword) {
                    // if the password matches we do this:
                    req.session.authenticated = true; // flag the session, all logged-in check now check if authenticated is true (this is required for the secured-area-check-middleware)
                    req.session.user = user; // this is optionally. I have done this because I want to have the user credentials available
                    // another benefit of storing the user instance in the session is
                    // that we can gain from the speed of redis. If the user logs out we would have to save the user instance in the session (didn't tried this)
                    res.send(200); // sent the client that everything gone ok
                } else {
                    res.send("wrong password", 500); // tells the client that the password was wrong (on production sys you want to hide what gone wronge)
                }
            });
        });
});

That was the login part lets go to the logout:

那是登录部分让我们去注销:

app.delete('/session', function(req, res) {
    // here is our security check
    // if you use a isAuthenticated-middleware you could make this shorter
    if (req.session.authenticated) {
        // this destroys the current session (not really necessary because you get a new one
        req.session.destroy(function() {
            // if you don't want destroy the whole session, because you anyway get a new one you also could just change the flags and remove the private informations
            // req.session.user.save(callback(err, user)) // didn't checked this
            //delete req.session.user;  // remove credentials
            //req.session.authenticated = false; // set flag
            //res.clearCookie('connect.sid', { path: '/' }); // see comments above                res.send('removed session', 200); // tell the client everything went well
        });
    } else {
        res.send('cant remove public session', 500); // public sessions don't containt sensible information so we leave them
    }
});

Hope this helps

希望这可以帮助