角度 4 不发送 cookie 到服务器

Posted

技术标签:

【中文标题】角度 4 不发送 cookie 到服务器【英文标题】:angular 4 not send cookie to server 【发布时间】:2018-06-11 23:53:12 【问题描述】:

当我使用 withCredentials 时,我可以看到 cookie 被发送到服务器。但是将任何内容发送到服务器。我使用 laravel 作为后端,使用 angular 4 作为前端。 此外,chrome 开发者工具上没有显示 cookie,我无法使用它们访问它们。

另外,我在 laravel 中使用了 Cors 中间件,例如:

<?php

namespace App\Http\Middleware;

use Closure;

class Cors

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    
      $response = $next($request);
      $response->headers->set('Access-Control-Allow-Origin', 'http://localhost:4200');
      $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
      $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Request-With');
      $response->headers->set('Access-Control-Expose-Headers', 'Content-Disposition, x-total-count, x-filename');
      $response->headers->set('Access-Control-Allow-Credentials', 'true');

      return $response;

    

当我第一次向服务器请求设置 cookie 时,以下响应显示:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, Accept, Authorization, X-Request-With
Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin:http://localhost:4200
Access-Control-Expose-Headers:Content-Disposition, x-total-count, x-filename
Cache-Control:no-cache, private
Connection:keep-alive
Content-Type:application/json
Date:Tue, 02 Jan 2018 09:04:32 GMT
Server:nginx/1.11.9
Set-Cookie:refreshToken=def502005a2ccf60eafdee2137df25a628d49f70c4571bedde628d50e45c0fe4b73f84f86bb469f0f77247dc2abc13c0c5c938027beb13fe534eb7bb41f4aed99faf49ebf2a238a007ce9514108951366db45a311d70d17d65dd48f5df6aa50f257c828cce16e589983c1e06c9e8d7d52806a1a9401569f87b3a394469e938c4ddbfcc7985e257d8f0d0df416e7b8a5bbd19e86050db3be5b90953c515934f529489f4e0ba62fb66ab883d1689349bbfb962332bceb322d978b7d20fa7e32bb94eb0050d8f94bfd3a780c4edfeea8eaa6954222b57c30229c2494fec38ee5292396400b25fadee04cad1729f9e9b9ccf12d21a6ed3f9663d41c5423536e64f83542df19fcede28247bfc12accf354e035182c3e019e4a2b55c807924cc50a12fa187b2f655fb19c1b42a1ae526763dd08dbd0d288b3a9c649216ab1abc60cd51bb97dfb0cb7b7b020ff270cf5c81bc94f2acd40f92edeefaf585d46d0750bf; expires=Sun, 25-Aug-2019 09:04:32 GMT; Max-Age=51840000; path=/; HttpOnly
Transfer-Encoding:chunked
X-RateLimit-Limit:60
X-RateLimit-Remaining:58

当我从前端请求时:

refreshToken()

const headers = new Headers( 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + this.getToken())
let options = new RequestOptions( headers: headers, withCredentials: true );
return this.http.post(API_DOMAIN + 'refresh', JSON.stringify(), options)
  .map(
    (response) => 
      console.log(response);
      return response.json()
    ,
  )
  .do(
    tokenData =>
      localStorage.setItem('token', tokenData.access_token)
      localStorage.setItem('expires_in', tokenData.expires_in)
    
  )

chrome 开发者:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, Accept, Authorization, X-Request-With
Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin:http://localhost:4200
Access-Control-Expose-Headers:Content-Disposition, x-total-count, x-filename
Cache-Control:no-cache, private
Connection:keep-alive
Content-Type:application/json
Date:Tue, 02 Jan 2018 08:57:28 GMT
Server:nginx/1.11.9
Transfer-Encoding:chunked
X-RateLimit-Limit:60
X-RateLimit-Remaining:59

前后端服务器使用不同的端口。

【问题讨论】:

你的 Laravel 服务器也运行 localhost 吗?为什么需要 CORS? @Dmitry 没有。我的 laravel 服务器在 homestead 和 domian 上运行,例如:mydomian.test 您无法向/从另一个域发送/接收 cookie。您需要代理到您的 Laravel 服务器(可以在 Angular 中配置)或使用其他身份验证方法,如 JWT 或其他基于令牌的身份验证。 @Dmitry 我使用 laravel 护照进行身份验证并在 laravel 服务器中编写中间件! 啊,所以它们不是身份验证cookie。但是无论如何您都不能将任何 cookie 发送到另一个域。您可以使用代理,然后您可以禁用 CORS,因为它可以在同一个域上工作。您只需要代理进行开发,因为当您发布整个应用程序时,您的整个应用程序将位于 Laravel 的 public 目录中。要不要我发一下如何配置代理? 【参考方案1】:

您可以保存 cookie,因为您的开发 node.js 服务器和您的 Laravel Vagrant 框位于不同的域中。您可以做的是将 node.js 的调用代理到 ​​Laravel 服务器。

在 Angular 应用的根目录中创建 proxy.conf.json。在里面放一个带有路由的对象:


  "/api": 
    "target": "http://mydomian.test/",
    "secure": false
  

我在这里只定义了/api,因为我所有的后端URI 都在api.php 中。所有看起来像http://localhost:4200/api/someitems/1 的呼叫都将被代理到http://mydomian.test/api/someitems/1。 然后编辑package.json,把scripts里面的start的值改成ng serve --proxy-config proxy.conf.json。现在npm run start 将从代理开始。我使用此代理遇到的问题是它将您的 URL (http://mydomian.test/) 解析为 IP。当它只用一个 IP 调用 Laravel 时,nginx 服务器不知道该做什么,因为它必须接收一个域名。 nginx 允许同一 IP 上的多个网站,因此它必须接收一个域名或拥有一个默认网站,它将所有没有域名的呼叫重定向到该网站。如果 Angular 的代理中仍未解决此问题,请转到 Laravel 机器上的 /etc/nginx/sites-available,您将在那里有一个 mydomian.test 配置文件。那里有listen 80; 行,将其更改为listen 80 default;

现在您可以将 API_DOMAIN 变量更改为 http://localhost:4200(或将其全部删除)并禁用 CORS。

【讨论】:

以上是关于角度 4 不发送 cookie 到服务器的主要内容,如果未能解决你的问题,请参考以下文章

cookie机制&跨域问题

从服务器接收的 Cookie 是安全的,但发送到服务器的 Cookie 不安全 ASP.NET

面试必备-HTTP协议-4

PouchDB + Couchbase + Sync Gateway Cookie身份验证

Javascript React 可以将 HttpOnly cookie 发送到服务器吗?

浅谈浏览器存储(cookielocalStoragesessionStorage)