Angular 4不向服务器发送cookie

3
当我使用withCredentials时,我可以看到cookie被发送到服务器。但是发送了什么给服务器呢?我使用laravel作为后端和angular 4作为前端。 此外,这些cookie不会显示在Chrome开发工具中,我无法访问它们。
另外,我在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

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


1
你的 Laravel 服务器也在本地运行吗?为什么需要 CORS? - Dmitry
@Dmitry 不是的。我的 Laravel 服务器运行在 Homestead 上,域名为:mydomain.test。 - Zione01
你不能向另一个域发送/接收 cookies。你需要通过代理到你的 Laravel 服务器(可以在 Angular 中配置)或使用另一种认证方法,如 JWT 或其他基于令牌的认证。 - Dmitry
@Dmitry 我使用 Laravel Passport 进行身份验证,并在 Laravel 服务器上编写了中间件! - Zione01
啊,所以它们不是身份验证 cookie。但是你无论如何都不能将任何 cookie 发送到另一个域。你可以使用代理,然后你可以禁用 CORS,因为它将在同一域上工作。你只需要在开发时使用代理,因为当你发布时,整个应用程序将位于 Laravel 的“public”目录中。你想让我发布如何配置代理的内容吗? - Dmitry
显示剩余2条评论
1个回答

4

由于您的开发node.js服务器和Laravel Vagrant框架位于不同的域,因此无法保存cookie。您可以通过从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。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接