繁体   English   中英

AngularJS会忽略HTTP标头中的Set-Cookie

[英]Set-Cookie in HTTP header is ignored with AngularJS

我正在开发一个基于客户端的AngularJS和服务器端的Java for my API(Tomcat + Jersey for WS)的应用程序。

我的API的某些路径受到限制,如果用户没有会话,则返回的响应状态为401.在客户端,拦截401 http状态以将用户重定向到登录页面。

用户通过身份验证后,我会在服务器端创建会话

httpRequest.getSession(true);
并且发送给客户端的响应确实在其标头中有Set-cookie指令:

\n 设置Cookie:JSESSIONID = XXXXXXXXXXXXXXXXXXXXX;  域本地主机=;  路径= / API /;  仅Http\n

问题是cookie永远不会放在客户端。 当我检查localhost域的cookie时它是空的,因此下一个请求的头部没有这个cookie,客户端仍然无法访问我的API的受限路径。

客户端和服务器位于同一个域中,但它们没有相同的路径和相同的端口号:

客户端: http://localhost:8000/app/index.html

服务器: http://localhost:8080/api/restricted/

附加信息:双方都启用了CORS:

  “访问控制允许 - 方法”,“获取,发布,选项”\n “Access-Control-Allow-Origin”,“*”\n “Access-Control-Allow-Credentials”,是的 

任何使Set-cookie正常工作的想法? 这是与AngularJS相关的问题吗?

在AngularJS中发现了一个帮助我前进的问题。

似乎"Access-Control-Allow-Credentials" : true未在客户端设置。 指令$httpProvider.defaults.withCredentials = true被忽略。

我在config参数中使用{withCredentials:true}通过简单的$ http调用替换$ resource调用。

我设法解决了一个与你非常相似的问题。 我的游戏! 后端尝试设置一个会话Cookie,我无法在Angular中捕获或通过浏览器存储。

实际上,解决方案涉及到一点点和一点点。

假设您已经解决了初始问题,只能通过向Access-Control-Allow-Origin添加特定域并删除通配符来解决,接下来的步骤是:

  1. 您必须从Set-Cookie标头中删除HTTP-Only,否则您将永远无法接收由角度代码“生成”的cookie
    此设置已在Firefox中运行,但不适用于Chrome

  2. 要使其适用于Chrome,您还需要:

    a)使用您的WS“托管”的域从cookie中的localhost发送不同的域。 你甚至可以使用通配符像.domain.com代替ws.domain.com

    b)然后您需要拨打您在Cookie中指定的域名,否则Chrome将不会存储您的Cookie

    [可选]我会删除/api路径以支持/


这应该是诀窍。
希望得到一些帮助

在客户端的发布请求中,请确保添加以下内容:

对于jquery ajax请求:

 $.ajax({ url: "http://yoururlgoeshere", type: "post", data: "somedata", xhrFields: { withCredentials: true } }); 

使用Angular的$ http服务:

 $http.post("http://yoururlgoeshere", "somedata", { withCredentials: true }); 

添加HttpOnly意味着浏览器不应该让插件和JavaScript看到cookie。 这是最近的安全浏览惯例。 应该用于J_SESSIONID但可能不在这里。

您需要在服务器端和客户端上工作。

客户

使用以下方法之一将$http config withCredentials设置$http true

  1. 按要求

     var config = {withCredentials: true}; $http.post(url, config); 
  2. 对于所有要求

     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-Credentialstrue

刚刚解决了这样的问题。

我这样做而且没有工作......:

  $cookies.put('JSESSIONID', response.data);

Cookie会保存在浏览器中,但是当我发送新请求时,所有Cookie都会被发送给我。 (我的cookie是JSESSIONID)

然后我看了铬检查员,我发现了这个: 我的会话是JsessionID

问题是,这不是正确的路径!

然后我尝试了这个,我的饼干被发送了。 好极了!

$cookies.put('JSESSIONID', response.data, {'path':'/'});

我不知道这是不是你的情况,但这对我有用。

问候!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM