简体   繁体   English

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

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

I'm working on an application based on AngularJS on client side and Java for my API (Tomcat + Jersey for WS) on server side. 我正在开发一个基于客户端的AngularJS和服务器端的Java for my API(Tomcat + Jersey for WS)的应用程序。

Some path of my API are restricted, if the user doesn't have a session the response status returned is 401. On the client side, 401 http status are intercepted to redirect the user to the login page. 我的API的某些路径受到限制,如果用户没有会话,则返回的响应状态为401.在客户端,拦截401 http状态以将用户重定向到登录页面。

Once the user is authenticated, I create a session on the server side 用户通过身份验证后,我会在服务器端创建会话

httpRequest.getSession(true);
and the response send to the client does have the Set-cookie instruction in its header : 并且发送给客户端的响应确实在其标头中有Set-cookie指令:

\nSet-Cookie:JSESSIONID=XXXXXXXXXXXXXXXXXXXXX; 设置Cookie:JSESSIONID = XXXXXXXXXXXXXXXXXXXXX; Domain=localhost; 域本地主机=; Path=/api/; 路径= / API /; HttpOnly 仅Http\n

The problem is that the cookie is never put on the client side. 问题是cookie永远不会放在客户端。 When I inspect cookie for localhost domain it's empty, so the next requests don't have this cookie in their header and client side still couldn't access to the restricted path of my API. 当我检查localhost域的cookie时它是空的,因此下一个请求的头部没有这个cookie,客户端仍然无法访问我的API的受限路径。

The client and the server are on the same domain but they don't have the same path and the same port number : 客户端和服务器位于同一个域中,但它们没有相同的路径和相同的端口号:

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

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

Additional info : CORS is enabled on the both side : 附加信息:双方都启用了CORS:

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

Any idea for making the Set-cookie works properly ? 任何使Set-cookie正常工作的想法? Is it an AngularJS related issue ? 这是与AngularJS相关的问题吗?

I found an issue in AngularJS that help me to move forward. 在AngularJS中发现了一个帮助我前进的问题。

It seems that "Access-Control-Allow-Credentials" : true was not set on the client side. 似乎"Access-Control-Allow-Credentials" : true未在客户端设置。 Instruction $httpProvider.defaults.withCredentials = true was ignored. 指令$httpProvider.defaults.withCredentials = true被忽略。

I replace $resource call by a simple $http call with {withCredentials:true} in the config parameter. 我在config参数中使用{withCredentials:true}通过简单的$ http调用替换$ resource调用。

I've managed to solve an issue very similar to yours. 我设法解决了一个与你非常相似的问题。 My Play! 我的游戏! backend tried to set a session Cookie which I could not catch in Angular or store via browser. 后端尝试设置一个会话Cookie,我无法在Angular中捕获或通过浏览器存储。

Actually the solution involved a bit of this and a bit of that. 实际上,解决方案涉及到一点点和一点点。

Assuming you've solved the initial issue, which can be solved only by adding a specific domain to the Access-Control-Allow-Origin and removing the wildcard, the next steps are: 假设您已经解决了初始问题,只能通过向Access-Control-Allow-Origin添加特定域并删除通配符来解决,接下来的步骤是:

  1. You have to remove the HTTP-Only from the Set-Cookie header, otherwise you will never be able to receive a cookie "generated" by your angular code 您必须从Set-Cookie标头中删除HTTP-Only,否则您将永远无法接收由角度代码“生成”的cookie
    This setup will already work in Firefox, though not in Chrome 此设置已在Firefox中运行,但不适用于Chrome

  2. To make it work for Chrome too, you need to: 要使其适用于Chrome,您还需要:

    a) send a different domain from localhost in the cookie, using the domain your WS are "hosted". a)使用您的WS“托管”的域从cookie中的localhost发送不同的域。 You can even use wildcards like .domain.com instead of ws.domain.com 你甚至可以使用通配符像.domain.com代替ws.domain.com

    b) then you'll need to make a call to the domain you specified in the cookie, otherwise Chrome won't store your cookie b)然后您需要拨打您在Cookie中指定的域名,否则Chrome将不会存储您的Cookie

    [optional] I would remove that /api path in favor of a / [可选]我会删除/api路径以支持/


And that should to the trick. 这应该是诀窍。
Hope to have been of some help 希望得到一些帮助

In your post request on the client side, make sure to add the following: 在客户端的发布请求中,请确保添加以下内容:

For jquery ajax requests: 对于jquery ajax请求:

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

With Angular's $http service : 使用Angular的$ http服务:

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

The addition HttpOnly means that the browser should not let plugins and JavaScript see the cookie. 添加HttpOnly意味着浏览器不应该让插件和JavaScript看到cookie。 This is a recent convention for securer browsing. 这是最近的安全浏览惯例。 Should be used for J_SESSIONID but maybe not here. 应该用于J_SESSIONID但可能不在这里。

You need work on both the server and client side. 您需要在服务器端和客户端上工作。

Client 客户

Set $http config withCredentials to true in one of the following ways: 使用以下方法之一将$http config withCredentials设置$http true

  1. Per request 按要求

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

     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 服务器

Set the response header Access-Control-Allow-Credentials to true . 将响应标头Access-Control-Allow-Credentialstrue

Just solved a problem like this. 刚刚解决了这样的问题。

I was doing this and not working...: 我这样做而且没有工作......:

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

Cookies are saved in the browser, but when I sent a new request, all the cookies were sent exept mine. Cookie会保存在浏览器中,但是当我发送新请求时,所有Cookie都会被发送给我。 (my cookie is JSESSIONID) (我的cookie是JSESSIONID)

then i look in the chrome inspector and i found this: 然后我看了铬检查员,我发现了这个: 我的会话是JsessionID

THE PROBLEM IS THAT WAS NOT THE CORRECT PATH!!! 问题是,这不是正确的路径!

then I tried this and my cookies were sent. 然后我尝试了这个,我的饼干被发送了。 yay! 好极了! :

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

I do not know if this is your case, but this worked for me. 我不知道这是不是你的情况,但这对我有用。

regards! 问候!

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

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