首页 文章

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

提问于
浏览
67

我正在研究基于客户端的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相关的问题吗?

6 回答

  • 12

    我找到了一个帮助我前进的issue in AngularJS .

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

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

  • 17

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

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

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

    • 您必须从 Set-Cookie Headers 中删除HTTP-Only,否则您将永远无法通过角度代码接收cookie "generated"
      This setup will already work in Firefox, though not in Chrome

    • 为了使其适用于Chrome,您还需要:

    a)使用您的WS为"hosted"的域从cookie中的localhost发送不同的域 . 您甚至可以使用 .domain.com 等通配符代替 ws.domain.com

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

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

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

  • 7

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

    对于jquery ajax请求:

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

    使用Angular的$ http服务:

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

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

  • 1

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

    Client

    使用以下方法之一将 $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;
              }
            };
          }
        ]);
      }
    ]);
    

    Server

    将响应标头 Access-Control-Allow-Credentials 设置为 true .

  • 7

    刚刚解决了这样的问题 .

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

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

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

    然后我看了铬检查员,我发现了这个:
    My session are the JsessionID

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

    然后我尝试了这个,我的 Cookies 被发送了 . 好极了! :

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

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

    问候!

相关问题