16

我的网络应用程序是这样的,当用户登录服务器时,会在响应中添加一个 Set-Cookie 标头,如下所示:

Set-Cookie:JSESSIONID=1; Path=/myApp/; Secure

注销时,我尝试在客户端(浏览器)上删除此 cookie,因为只要删除 cookie,我就不关心会话是否在服务器上成功销毁。任何挥之不去的“幽灵”会话将不时在服务器上清理。

但是,我的应用无法删除 JSESSIONID cookie。假设从调用https://test.myserver.com/myApp/app/index.html#/mySubPage注销函数并且注销函数执行以下操作:

delete $cookies["JSESSIONID"];
$location.path("/login");

cookie 没有被删除。刷新 Chrome 开发者工具中“资源”选项卡中的 cookie 列表显示它仍然存在。重新加载登录页面并刷新“资源”选项卡中列出的 cookie 仍会显示 cookie。

当它不是 HTTPOnly cookie 时,为什么我不能从我的 Javascript 客户端删除 cookie?是导致问题的路径吗?不应该,因为脚本在 cookie 路径中包含的页面上运行。通常处理 Cookie 并没有那么难,所以我很清楚我在这里可能忽略了一些微不足道的事情 - 但任何帮助将不胜感激。

更新:

我在原始帖子中给出了错误的应用程序路径。它现在被编辑以反映正确的路径(嗯,抽象地)。事实证明,这是该问题的关键信息。AngularJS 使用应用程序的完整相对路径作为它创建/删除的所有 cookie 的路径属性,因此由于我们的服务器将 cookie 设置为路径/myApp/并且应用程序在相对路径上运行/myApp/app,Angular 试图删除前者cookie,不存在(为了覆盖或删除现有的 cookie,名称、域和路径都需要与创建 cookie 时使用的相同)。

4

3 回答 3

11

我想你应该检查来自服务器的响应——也许它们包含一个设置 cookie 值的“set cookie”标题字段。

这是一个Plunker 示例,说明了如何添加/更改/删除/监视 cookie 的值(但没有可以更改 cookie 值的服务器端响应)。

但通常,$cookies 对象是一种“代理对象”,由 AngularJS ngCookies 模块双向跟踪,当浏览器的 cookie 更改时,从一侧更改其字段(因此您可以 $watch 更改),但更改也会反映到浏览器的真实 cookie,因此您可以更改此对象。

所以无法删除cookie的唯一原因是您在浏览器上删除它们,服务器再次设置cookie,重新加载页面后它仍然存在。

于 2013-01-07T16:13:09.750 回答
5

请注意要删除的 cookie 的 cookie 域。如果您使用多个子域(即一个用于静态资源,另一个用于 api),您的问题可能是您试图删除错误域的 cookie。

使用您选择的浏览器开发工具查看您的 cookie。为您遇到问题的要删除的 cookie 设置了任何域,请在 remove 方法的 options 参数中指定它。

$cookies.remove('JSESSIONID', {domain: 'domain.tld'});

安全提示:通过 Javascript 删除会话 ID 不会删除服务器上的会话。如果您的会话 ID 泄漏,您可能会遭受会话固定的困扰。最好通过调用 API 中的注销端点来删除 cookie,这将完全清除服务器上的会话,使其无法重复使用。

于 2015-10-26T21:28:01.247 回答
3

您在更新中给出的答案似乎是正确的:Angular$cookieStore只能处理路径值与当前路径相同的 cookie。

欺骗它的方法是使用 ajspera 在这个问题上给出的解决方案:

<head>
  <base href="/">
</head>

只需添加<base href="/">到 HTML 的 head 元素中,然后它就可以工作了。

另一种解决方案是使用发送它的服务器设置 cookie 的路径。在 Node.js Express 中看起来像

res.cookie('specialCookie', 'special!', {path: '/myApp'});

请注意,对我来说,$cookieStore 似乎去掉了斜杠,所以你可能需要两种方式都尝试。

于 2014-08-18T22:34:24.253 回答