【问题标题】:Angular 5 HttpClient ignores Set-Cookie header from wordpress REST api post responseAngular 5 HttpClient 忽略来自 wordpress REST api 发布响应的 Set-Cookie 标头
【发布时间】:2018-04-12 20:01:29
【问题描述】:

我用谷歌搜索了很多,但我似乎无法找到我的问题的明确答案。很多类似的情况/解决方案,但没有一个对我有用。

我的设置如下:

环境:在 Angular 5 之上运行的 XAMP、Wordpress 4.9 和 Angular Material Design

后端(REST API 服务器): 我有一个完整的 Wordpress 设置,在地址运行顺利:http://localhost/~XXXX/wordpress。 我打算使用 only 后端,以便通过内置的 json REST API 接口向客户端提供数据,为此我设置了一个自定义/测试端点,如下所示:

add_action('rest_api_init', function () {

    register_rest_route('cookie-test/v1', 'set', [
      'methods' => 'POST',
      'callback' => function () {
          setcookie('cookieKey', $_POST['cookieValue'], time()+60*60*24*30);
          return [
            'responseKey' => 'responseValue',
          ];
      },
    ]);
});

实际上,我正在尝试为前端实现某种基于 cookie 的身份验证,不是基于 wordpress 的! 这个(伪)代码基本上是一个测试平台,用于检查后端和前端之间的正确 cookie 功能/交换。

前端:(部分)

// auth.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';

@Injectable()
export class AuthService
{
    constructor(
        private http: HttpClient
    )
    {
    }

    cookieTest() {
        return this.http.post(
            'http://localhost/~XXXX/wordpress/wp-json/cookie-test/v1/set',
            {cookieValue: 'randomValue'},
            {
                observe: 'response', // Full response instead of the body only
                withCredentials: true, // Send cookies
            }
        );
    }
}

// login.component.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { Router } from '@angular/router';
import { AuthService } from '../services/auth.service';

@Component({
    selector   : 'login',
    templateUrl: './login.component.html',
    styleUrls  : ['./login.component.scss'],
})

export class LoginComponent implements OnInit
{
    loginForm: FormGroup;
    loginFormErrors: any;

    constructor(
        private formBuilder: FormBuilder,
        private authService: AuthService,
        private router: Router,
    )
    {
        this.loginFormErrors = {
            email   : {},
            password: {}
        };
    }

    ngOnInit()
    {
        this.loginForm = this.formBuilder.group({
            email   : ['', [Validators.required, Validators.email]],
            password: ['', Validators.required],
        });
    }

    onCookieTest()
    {
        this.authService.cookieTest()
            .subscribe(
                response => {
                    const keys: string[] = response.headers.keys();
                    console.log(keys);
                    console.log(response);
                },
                error => {
                    console.log(error);
                }
            );
    }
}

问题: 前端可以到达 wordpress REST API 端点,进而正确响应 angular 'post' 请求,但是...但是 cookie 没有设置在浏览器中!

我可以从浏览器的调试器控制台看到 POST 响应中的 Set-Cookie 标头存在,并且具有正确的字段,但显然浏览器(或 Angular 的 HttpClient?)完全忽略了它!

谷歌搜索我找不到任何关于 /Angular5 的信息。各种后端(ruby、laravel、java、C# 等),但与 Angular5 的 HttpClient 的 Wordpress 无关。

这些是标题:

请求(选项)

Access-Control-Request-Headers  content-type
Referer http://localhost:4200/auth/login
Origin  http://localhost:4200
Accept  */*
User-Agent  ...
Access-Control-Request-Method   POST

响应(选项)

Transfer-Encoding   Identity
Connection  Keep-Alive
X-Powered-By    PHP/7.0.14
Access-Control-Allow-Methods    OPTIONS, GET, POST, PUT, PATCH, DELETE
Access-Control-Expose-Headers   X-WP-Total, X-WP-TotalPages
Vary    Origin
Access-Control-Allow-Headers    x-wp-nonce, Authorization, Content-Type
Server  Apache/2.4.16 (Unix) PHP/7.0.14 OpenSSL/0.9.8zg
Content-Type    application/json; charset=UTF-8
Access-Control-Allow-Credentials    true
Date    Thu, 12 Apr 2018 19:20:43 GMT
Access-Control-Allow-Origin http://localhost:4200
Keep-Alive  timeout=5, max=100
X-Content-Type-Options  nosniff
X-Robots-Tag    noindex
Link    <http://localhost/~XXXX/wordpress/wp-json/>; rel="https://api.w.org/"
Allow   POST

请求(POST)

DNT 1
Content-Type    application/json
Referer http://localhost:4200/auth/login
Accept  application/json, text/plain, */*
User-Agent  ...
Origin  http://localhost:4200

响应 (POST)

Transfer-Encoding   Identity
Connection  Keep-Alive
X-Powered-By    PHP/7.0.14
Access-Control-Allow-Methods    OPTIONS, GET, POST, PUT, PATCH, DELETE
Set-Cookie  cookieKey=randomValue; expires=Sat, 12-May-2018 19:20:53 GMT; Max-Age=2592000
Access-Control-Expose-Headers   X-WP-Total, X-WP-TotalPages
Vary    Origin
Access-Control-Allow-Headers    x-wp-nonce, Authorization, Content-Type
Server  Apache/2.4.16 (Unix) PHP/7.0.14 OpenSSL/0.9.8zg
Content-Type    application/json; charset=UTF-8
Access-Control-Allow-Credentials    true
Date    Thu, 12 Apr 2018 19:20:52 GMT
Access-Control-Allow-Origin http://localhost:4200
Keep-Alive  timeout=5, max=100
X-Content-Type-Options  nosniff
Link    <http://localhost/~XXXX/wordpress/wp-json/>; rel="https://api.w.org/"
X-Robots-Tag    noindex
Allow   POST

提前感谢您的任何帮助/提示

【问题讨论】:

  • 尝试设置路径setcookie('cookieKey', $_POST['cookieValue'], time()+60*60*24*30, '/')
  • @大卫宾果!!!如果您发表您的评论作为答案,我会将其标记为正确的!!!非常感谢大卫!!!

标签: wordpress angular rest cookies httpclient


【解决方案1】:

您需要在后端指定路径(例如根路径)

setcookie('cookieKey', $_POST['cookieValue'], time()+60*60*24*30, '/')

如果您在设置 cookie 时未指定路径,则它将仅在当前路径 (.../wp-json/cookie-test/v1/set) 上可用,这意味着 cookie 在以后的请求中不会被发送到您的后端,如果您在该域上尝试不同的路径

【讨论】:

  • 再次感谢您,大卫。实际上,我的斗争是“反对” wordpress。如果我尝试像这样设置 cookie(这是 wordpress 所做的)setcookie('cookieKey', $_POST['cookieValue'], time()+60*60*24*30, '/localhost/~XXXX/wordpress/plugins');,则 cookie 在端口 4200 上不可见。它仅在您使用 wordpress 的前端时才有效,这是我试图避免的。谢谢
  • 谢谢你,大卫,谢谢你的提示,我正在设法度过难关......谢谢
猜你喜欢
  • 2021-02-25
  • 1970-01-01
  • 2019-03-26
  • 2011-09-27
  • 2018-06-14
  • 2019-06-20
  • 2018-08-29
  • 1970-01-01
  • 2017-05-25
相关资源
最近更新 更多