首先,区分客户端的 cookie 和服务器端的会话很重要(我想你已经知道了)。
通常,为了彻底注销,您需要session.invalidate()
在服务器端和Cookies.removeCookie(...)
客户端调用。
但并非每个“注销”都是干净的:
- 注销请求可能无法到达服务器
- 浏览器可能在您调用 removeCookie 之前崩溃 - 因此任何在关闭窗口时删除 cookie 的尝试都是不可靠的
在服务器端,您可以使用超时(请参阅@thinksteep 提供的链接:我们如何在浏览器关闭事件中调用 logout servlet)。
对于客户端 cookie,您可以设置 expiryDate/maxAge。或者您可以使用“会话 cookie”:这些是您根本不设置到期或 maxAge 的 cookie。大多数浏览器会在浏览器重新启动时自动删除“会话 cookie” - 但请参阅Firefox 会话 cookie。
所有这一切可能意味着,cookie 可能不是最适合您的用例的技术:通常,cookie 在设计上适用于所有浏览器选项卡,并且浏览器会话的概念甚至并不总是结束,当浏览器/window 关闭(这在智能手机上意味着什么?)。这对于许多当前的网站来说是可取的(用户不必每次都显式登录),并且许多用户已经开始期待这种行为。
对于需要“一个选项卡 = 一个会话”策略的站点,最好将令牌存储在例如 Javascript(或 GWT)对象中,并随每个请求一起发送。这样,您可以从多个浏览器选项卡单独登录(即使作为不同的用户),一旦选项卡关闭,令牌就消失了。请注意,在会话恢复时,浏览器可能仍会恢复选项卡。(我总是将这种技术与 httponly cookie 结合起来,以避免某些类型的攻击。)