预检标题不符合预期

Posted

技术标签:

【中文标题】预检标题不符合预期【英文标题】:Preflight Headers Not As Expected 【发布时间】:2019-12-06 04:55:50 【问题描述】:

我正在尝试从 Angular 8 应用程序向 Laravel 5.8 Passport API 发送请求,但没有成功。我的意思是,只有有限的成功。当我将 Angular 请求中的 withCredentials 设置为 true 时,Preflight 标头试图查看 API 是否会返回正确的标头,包括 Access-Control-Allow-Credentials: true,但响应显示没有这样的标头,即使我'正在将其设置到后端。

如果我不设置 withCredentials,则响应标头包含 Access-Control-Allow-Credentials: true,正如预期的那样,但我也需要在预检响应中使用该响应。

我尝试使用

将预检请求案例封装在单独的块中
    if (!$_SERVER['REQUEST_METHOD']=='OPTIONS')

并明确设置该标头响应,但也没有成功。 附带说明的是,从 Postman 请求相同的 URL 可以按预期工作(因为 Postman 不会与 CORS 混淆)。

请求是从以下代码 sn-p 触发的:

    await this.http.post(this.logInEndPoint, credentials, 
        headers: this.httpHeaders,
        withCredentials: true
    ).subscribe(async res => 
    ...

CORS 中间件如下所示:

    $res->headers->set('Content-Type', 'application/json');
    $res->headers->set('Access-Control-Allow-Origin', 'http://127.0.0.1:4200');
    $res->headers->set('Access-Control-Allow-Credentials', 'true');
    $res->headers->set('Access-Control-Max-Age', '60');
    $res->headers->set('Access-Control-Allow-Headers', 'x-requested-with, Content-Type, origin, authorization, accept, client-security-token');
    $res->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

    if (!$_SERVER['REQUEST_METHOD']=='OPTIONS') 
      $next($res);
     else 
      return $res;
    

这就是我定义使用 CORS 中间件的地方 api.php

    Route::middleware('web', 'json.response', 'cors')->group(function() 
       Route::post('login', 'AuthController@login');

    ...

我期待“成功登录”消息,但从源“http://127.0.0.1:4200”获得对 XMLHttpRequest 的访问权限已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:响应中“Access-Control-Allow-Credentials”标头的值为“”,当请求的凭据模式为“包含”时,该值必须为“真”。 XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制。在开发者工具中。

【问题讨论】:

【参考方案1】:

在解决这个问题几天后,我终于弄明白了。 如果我必须总结与使用 Laravel API 的 Angular 相关的大多数问题,我会指出后端的标头设置。对我来说,它位于自定义 CORS 中间件中的某个位置。 老实说,我不确定上面的配置到底出了什么问题(我猜是在 Allow-Methods 标头中),但我会分享我是如何解决我的问题的。 首先,我删除了我制作的所有自定义中间件。我开始使用Barry vd. Heuvel's CORS 一个,只为API 组添加它。在那里,我更改了默认配置。我将 allowOrigins 设置为我的 Angular 服务器 URI,将 allowedMethods 设置为我期望使用的请求。发布 CORS 配置文件后,我确保在 127.0.0.1(而不是 localhost)上运行我的 Angular 应用程序。我为 Laravel 服务器所做的相同。 在同一个 IP 地址上运行这两个应用程序并使用新的 CORS 中间件后,一切运行顺利且没有问题。

【讨论】:

以上是关于预检标题不符合预期的主要内容,如果未能解决你的问题,请参考以下文章

参数类型 '[HKCategoryType?]' 不符合预期的类型 'Hashable'

参数类型 'SecretSpec' 不符合预期的类型 'Sequence'

PriorityQueue 的顺序不符合预期[重复]

子字符串输出不符合预期?

mysql函数的输出不符合预期

变量的行为不符合预期