【问题标题】:Cookie not being set on angular clientCookie 未在 Angular 客户端上设置
【发布时间】:2020-10-21 17:56:51
【问题描述】:

我在 django python 中有一个后端应用程序,它在 http://localhost:8000 上提供服务。

我有一个 Angular 前端,它在 http://localhost:4200 上提供服务。

我在 django 上禁用了 CORS。 在 http://localhost:8000/auth/login/ 上点击登录 api 时,我得到了有效的响应 连同 Set-Cookie 标头。

这是我打印 cookie 的 Angular 代码:

  this.http.post<any>('http://localhost:8000/auth/login/', this.LoginForm, { observe: 'response' }).subscribe(response => {
   console.log("response is ", response);
   var cookies = this.cookieService.getAll();//('cookies');
   console.log("cookies is :", cookies);

它在控制台上打印一个空对象。 我该如何进行这项工作?我想使用 cookie 进行身份验证。

【问题讨论】:

    标签: django angular cookies


    【解决方案1】:

    您正在尝试设置跨域 cookie,这不会立即生效。要做到这一点,需要遵循几个步骤。

    1. 从 Angular 发出身份验证请求时设置 withCredentials: true

      this.http.post&lt;any&gt;('http://localhost:8000/auth/login/', this.LoginForm, { observe: 'response', withCredentials: true })

    2. 配置您的服务器以返回以下 CORS 标头:Access-Control-Allow-Credentials: true 和 Access-Control-Allow-Origin: http://localhost:4200

    注意

    您设置的其中一个 cookie 是 HttpOnly。因此,您无法从 Javascript 访问它(请参阅 documentation)。

    无论如何,您可能不需要使用 JS 访问 cookie。如果你只是想在下一个 API 请求中发送 cookie,只需将 withCredentials: true 传递给 HttpClient 其他 api 调用

    this.http.get('http://localhost:8000/path/to/get/resource',
      { withCredentials: true }).subscribe(response => {
    

    【讨论】:

      【解决方案2】:

      设置 Cookie:

      在问题的示例中,客户端和服务器都在同一个域 localhost 中。 在部署时,情况可能并非如此。 让我们假设域如下,
      • 客户端:client1.client.com
      • 服务器:server1.server.com

      来自 client1.client.com 到 https://server1.server.com/api/v1/getSomething 的 Angular Web 应用程序的 http 请求在响应标头中有 Set-Cookie: JSESSIONID=xyz。 cookie 将设置在 server1.server.com 而不是 client1.client.com。 您可以在网址栏中输入server1.server.com 并查看正在设置的cookie。

      withCredentials:

      Angular 应用程序无需读取 cookie 并在以下请求中发送它。 withCredentials http 请求的属性可以用于此。 参考:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials

      例子:

      public getSomething(): Observable<object> {
          const httpOptions = {
            withCredentials: true
          };
          return this.http.get(`${this.serverUrl}/getSomething`, httpOptions);
        }
      

      参考:https://angular.io/api/common/http/HttpRequest

      withCredentials 将在对服务器的请求中设置来自服务器域的 cookie。

      如前所述,Set-Cookie: JSESSIONID=xyz 在来自server1.server.com 的响应中将设置为server1.server.com。 client1.client.com 中的 Angular 应用程序不需要阅读它。 withCredentials 会处理的。

      跨域问题:

      当服务器和客户端在不同的域中时,使用 withCredentials 可能无法在所有浏览器中工作,因为它们被视为第三方 cookie。

      在我最近于 2020 年 5 月进行的测试中,我发现当客户端和服务器位于不同的域中时,withCredentials 在某些浏览器中不起作用。

      同域:

      看起来主流浏览器正在阻止第三方 cookie。

      解决方案是让客户端和服务器在同一个域中。

      • 客户端:client1.myapp.com
      • 服务器:server1.myapp.com

      在Set-Cookie 响应中也包含根域。 示例:“JSESSIONID=xyz;域=.myapp.com;路径=/”

      这将确保在所有情况下都设置了 cookie。

      【讨论】:

      • 这张图片(浏览器兼容性表)来自哪里?
      猜你喜欢
      • 2023-03-03
      • 1970-01-01
      • 2014-03-31
      • 2013-12-02
      • 2012-08-17
      • 1970-01-01
      • 1970-01-01
      • 2019-07-30
      • 2013-01-25
      相关资源
      最近更新 更多