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

Rom*_*ois 67 javascript cookies setcookie angularjs

我正在开发一个基于客户端的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相关的问题吗?

Rom*_*ois 21

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

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

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

  • 如果您找到了解决方案,请不要忘记发布答案.如果您的客户端是移动的并且您正在使用phonegap/cordova或本机客户端,您是否尝试覆盖origin/refferer标头并使用常量源? (3认同)

dom*_*kun 18

我设法解决了一个与你非常相似的问题.我的游戏!后端试图设置一个会话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路径以支持a/


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


Tel*_*iov 14

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

对于jquery ajax请求:

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

使用Angular的$ http服务:

$http.post("http://yoururlgoeshere", "somedata", {
  withCredentials: true
});
Run Code Online (Sandbox Code Playgroud)


小智 9

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

客户

通过以下方式之一将$httpconfig 设置withCredentialstrue:

  1. 按要求

    var config = {withCredentials: true};
    $http.post(url, config);
    
    Run Code Online (Sandbox Code Playgroud)
  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;
              }
            };
          }
        ]);
      }
    ]);
    
    Run Code Online (Sandbox Code Playgroud)

服务器

将响应标头设置Access-Control-Allow-Credentialstrue.

  • 不需要创建拦截器,现在你可以使用这个`$ httpProvider.defaults.withCredentials = true;` (2认同)

Joo*_*gen 7

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