我正在开发一个基于客户端的AngularJS和服务器端的Java for my API(Tomcat + Jersey for WS)的应用程序。
我的API的某些路径受到限制,如果用户没有会话,则返回的响应状态为401.在客户端,拦截401 http状态以将用户重定向到登录页面。
用户通过身份验证后,我会在服务器端创建会话
httpRequest.getSession(true);并且发送给客户端的响应确实在其标题中包含Set-cookie指令:
Set-Cookie:JSESSIONID=XXXXXXXXXXXXXXXXXXXXX; Domain=localhost; Path=/api/; HttpOnly
问题是cookie永远不会放在客户端。当我检查localhost域的cookie时它是空的,所以下一个请求的头部没有这个cookie,客户端仍然无法访问我的API的受限路径。
客户端和服务器位于同一个域中,但它们没有相同的路径和相同的端口号:
客户:http://localhost:8000/app/index.html
服务器:http://localhost:8080/api/restricted/
附加信息:双方都启用了CORS:
"Access-Control-Allow-Methods", "GET, POST, OPTIONS" "Access-Control-Allow-Origin", "*" "Access-Control-Allow-Credentials", true
任何让Set-cookie正常工作的想法? 这是与AngularJS相关的问题吗?
答案 0 :(得分:21)
我发现issue in AngularJS可以帮助我继续前进。
似乎"Access-Control-Allow-Credentials" : true
未在客户端设置。
指令$httpProvider.defaults.withCredentials = true
被忽略了。
我在config参数中使用{withCredentials:true}通过简单的$ http调用替换$ resource调用。
答案 1 :(得分:17)
我设法解决了一个与你非常相似的问题。 我的游戏!后端尝试设置会话Cookie,我无法通过Angular捕获或通过浏览器存储。
实际上,解决方案涉及到一点点和一点点
假设您已经解决了初始问题,只能通过向Access-Control-Allow-Origin添加特定域并删除通配符来解决,接下来的步骤是:
您必须从Set-Cookie
标题中删除HTTP-Only,否则您将永远无法接收由角度代码“生成”的Cookie
此设置已在Firefox中使用,但不在Chrome中
要使其适用于Chrome,您需要:
a)使用您的WS“托管”的域从cookie中的localhost发送不同的域。您甚至可以使用.domain.com
之类的通配符代替ws.domain.com
b)然后您需要拨打您在Cookie中指定的域名,否则Chrome将不会存储您的Cookie
[可选]我会删除该/api
路径,转而使用/
这应该是诀窍。
希望得到一些帮助
答案 2 :(得分:13)
在客户端的帖子请求中,请务必添加以下内容:
对于jquery ajax请求:
$.ajax({
url: "http://yoururlgoeshere",
type: "post",
data: "somedata",
xhrFields: {
withCredentials: true
}
});

使用Angular的$ http服务:
$http.post("http://yoururlgoeshere", "somedata", {
withCredentials: true
});

答案 3 :(得分:7)
添加HttpOnly意味着浏览器不应该让插件和JavaScript看到cookie。这是最近的安全浏览惯例。应该用于J_SESSIONID,但可能不在这里。
答案 4 :(得分:7)
您需要在服务器端和客户端上工作。
<强>客户端强>
通过以下方式之一将$http
config withCredentials
设置为true
:
按要求
var config = {withCredentials: true};
$http.post(url, config);
对于所有请求
angular.module("your_module_name").config(['$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push(['$q',
function($q) {
return {
request: function(config) {
config.withCredentials = true;
return config;
}
};
}
]);
}
]);
服务器强>
将回复标题Access-Control-Allow-Credentials
设置为true
。
答案 5 :(得分:1)