Angular 不随请求发送 cookie

pau*_*l41 7 cookies angular

我正在从服务器设置一个仅 http 的 cookie,并且可以看到 cookie 已设置,但是当我向服务器发送请求时,不包含 cookie。

在服务器端 CORS 设置为:

  1. 允许来源:http://localhost:4200
  2. 允许标头:X-Requested-With、Accept、Observe、Content-Type 和 Authorization
  3. 允许方法:GET、POST、HEADER、PUT、DELETE 和 OPTIONS
  4. 允许凭据: true

我可以看到cookie已设置,但设置cookie后向服务器发出的请求不包含cookie。

我如何从服务器请求的示例是:

getUserInfo(): Observable<User> {
    const httpOptions = {
        headers: new HttpHeaders({
            'Content-Type': 'application/json'
        }),
        withCredentials: true
    };

}
Run Code Online (Sandbox Code Playgroud)

如您所见,我已将 withCredentials 设置为 true,但我的 cookie 仍未发送。

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: localhost:8080
Origin: http://localhost:4200
Referer: http://localhost:4200/login
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36
Run Code Online (Sandbox Code Playgroud)

我还需要做什么才能发送 cookie?

Mic*_*ely 5

如果服务器上的 cookie 设置是正确的,并且 Angular 仍然没有发送服务器之前设置的 cookie,那么可能会发生这种情况,因为您在端口 4200 上使用 Angular 的开发服务器运行和测试它,而 API 服务器正在运行不同的端口。

仅当 cookie 的“Domain”属性与所请求的 URL 的域匹配时,浏览器才会自动将 cookie 与请求一起发送到服务器(当设置 cookie 时,可以为其分配一个“Domain”属性,该属性限制cookie 到特定子域或域),以及当向与 cookie 域匹配的 URL 发出请求时。

在上面的问题中,您的 Angular 开发服务器(和 Angular 应用程序)可能在 上运行http//localhost:4200,而 API 服务器也在 上运行,例如,在 上运行http//localhost:3000。在这种情况下,由于端口是域的一部分,浏览器不会将 cookie 与对 API 的请求一起附加。

要解决此问题,您可以将代理设置添加到 Angular 应用程序中:

  1. 将域更改为 Angular 应用程序中所有直接 URL 中的前缀。即更改http//localhost:3000/your-api-route/api/your-api-route. 例如:
// Change
this.http.get<User>('http://localhost:3000' + '/auth/whoami', { withCredentials: true });
this.http.post<User>('http://localhost:3000' + '/auth/whoami', null, { withCredentials: true });

// To
this.http.get<User>('/api' + '/auth/whoami', { withCredentials: true });
this.http.post<User>('/api' + '/auth/whoami', null, { withCredentials: true });     
Run Code Online (Sandbox Code Playgroud)
  1. proxy.conf.json在项目的文件夹中创建一个文件src/

  2. 将以下内容添加到新的代理文件中,其中pathRewrite- 用来删除我们替换为/api时添加的前缀:http://localhost:3000/api

{
  "/api": {
    "target": "http://localhost:3000",
    "secure": false,
    "pathRewrite": {
            "^/api": ""
        }
  }
}
Run Code Online (Sandbox Code Playgroud)
  1. 在 CLI 配置文件中,将选项angular.json添加proxyConfig到服务目标:
...
  "architect": {
    "serve": {
      "builder": "@angular-devkit/build-angular:dev-server",
      "options": {
        "browserTarget": "your-application-name:build",
        "proxyConfig": "src/proxy.conf.json"
      },
...
Run Code Online (Sandbox Code Playgroud)
  1. 要使用此代理配置运行开发服务器,请调用ng serve

现在,浏览器将自动将运行在 上的服务器使用“set-cookie”标头设置的 cookie 附加http://localhost:3000到从 Angular 应用程序(在 上运行http://localhost:4200)到在 上运行的服务器的任何请求http://localhost:3000

请注意,您需要http://localhost:3000在生产中进行更改。您可能需要多个代理设置,每个环境一个。但是,如果您的 Angular 应用程序由 API 服务器提供服务(即服务器在同一端口上提供的静态目录),则不需要代理设置。