401 错误 - 使用 fetch 找不到 JWT 令牌

401 error - JWT Token not found using fetch

我是新手,主要是 javascript。 我在 localhost:3000 上使用 node.js 和 symfony 2.8 作为我的后端使用 React,在 localhost:80 上使用 apache,它暴露了一个 api 安全的 lexik和 fos 用户。 在保护 api 之前,一切正常。 确保 api 安全后,我在使用 fetch 时收到 401 错误,如下所示:

let myToken = localStorage.getItem('auth_token') //token properly retrieved
let myHeaders = new Headers();
myHeaders.append("Authorization", myToken)
return fetch(
    pathToMyResource,
    {
        method: "post",
        headers: myHeaders
    }
).then(do stuff with the answer)

这让我在 headers 的预检请求答案中出现以下错误:

Request URL:http://127.0.0.1/edsa-food_app_symfony_2.8/api/site/1/get
Request Method:OPTIONS
Status Code:401 Unauthorized
Remote Address:127.0.0.1:80
Referrer Policy:no-referrer-when-downgrade

响应:

{"code":401,"message":"JWT Token not found"}

我也查了一下,只是因为我不太明白这是怎么回事,

credentials: 'include'

mode: 'no-cors'

但并没有更成功。

当我使用来自 localhost:8000 的 php 构建并发送相同的请求时,它运行良好。我使用以下代码:

$url = pathToMyResource
$options = array(
    'http' => array(
        'header'  => "Authorization: Bearer $token"
        'method'  => 'POST',
    )
);

$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
var_dump($result);

如果我理解得很好,那不可能是 中描述的 apache 错误:任何 symfony 2.8 项目根目录中的默认 .htaccess 包括:

RewriteEngine On
RewriteCond %{REQUEST_URI}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]

我检查过 mod_rewrite 已启用。

以下是 Chrome 中报告的 headers:

**General**
Request URL:http://127.0.0.1/edsa-food_app_symfony_2.8/api/site/1/get
Request Method:OPTIONS
Status Code:401 Unauthorized
Remote Address:127.0.0.1:80
Referrer Policy:no-referrer-when-downgrade

**Response Headers**
view source
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Connection:Keep-Alive
Content-Length:44
Content-Type:application/json
Date:Tue, 08 Aug 2017 01:05:20 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.18 (Win32) PHP/5.6.19
WWW-Authenticate:Bearer
X-Powered-By:PHP/5.6.19

**Request Headers**
view source
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en;q=0.8,en-US;q=0.6,fr;q=0.4,zh-CN;q=0.2,zh;q=0.2,it;q=0.2
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:POST
Connection:keep-alive
Host:127.0.0.1
Origin:http://localhost:3000
Referer:http://localhost:3000/service-worker.js
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

对于 POST 请求本身:

**General**
Request URL:http://127.0.0.1/edsa-food_app_symfony_2.8/api/site/1/get
Referrer Policy:no-referrer-when-downgrade

**Request Headers**
Provisional headers are shown
authorization:Bearer eyJhbGciOiJSUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX1VTRVIiXSwidXNlcm5hbWUiOiJhbnRvaW5lIiwiaWF0IjoxNTAyMTM4ODUwLCJleHAiOjE1MDIyMjUyNTB9.wpWZZLf5wWjrU0-eAQUR0XiDTvf1jRtiJuGIHoYm7Yo4lGhOn-_bYuJIdv71ZUiuYfaaMxOW4xzXN3JjB9KfrWmXD4jqI6CnHFYZISGlYvAGJayD_z8CMIEdvrMXrbb6_nEc0CaB68BOf7wqJyoNatFKlepwmCHevsRtTIbhc_GviQf_U_Fw30ShtogIJBLqmVD4ex-j0_9QbblAIqNhc8c0thEFYtN7FVepLehCzBNCTNL8l-mxYEFTrUYLKwSt4lRahgTsv4Ozhxl300xz7BbdQEr3ph2i4ssVcvokpEO2C07QicWSwXFx1Vx-2a6XbkoeorTz_P7WstBzinMdv0etlIz2VYN_oUmHaxDu9jlsu90nZlL2Ea7Ak7dSJaNYzmB11yga_OSiWMpzWTjaqP3MLJuS1O5keHMbliERgnBJM_rsMZ-mkVSM8j4t31L1QJCfP0RW-Vfj3biYR1uYNfXwbbdqmIpn6b39qOCY9l4F99dK6R-PKq5ZeBHEfy-OpN39NFmaMQQX5gYCQ3TzVdeou6-hjpqRnNl8dc0HYzAl3fbU102JMefZNvCsIdcI6WDCiyWZO9Viy-z9REAVF4Pr9bLFpc-Q6Lqdj32lt1-yy6i75IOavrPqRilhRh2z_V7rP_DqahrLhFSDPPVg_gcqb8n31_6q3wtyzx16aJ4
Origin:http://localhost:3000
Referer:http://localhost:3000/restaurant
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

我迷路了

您需要配置后端,以便它使用 200 或 204 响应预检。

您可以通过添加您的 Apache 配置来在 Apache 级别处理此问题:

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$  [R=200,L]

但如果这不能解决,那么您将需要进一步挖掘并找出后端系统的哪个部分导致 OPTIONS 请求需要身份验证。

原因是因为这里发生的事情是这样的:

  1. 您的代码告诉您的浏览器它想要发送带有 Authorization header.
  2. 的请求
  3. 你的浏览器说,好的,带有 Authorization header 的请求需要我进行 CORS 预检 OPTIONS 以确保服务器允许带有 header 的请求.
  4. 您的浏览器将 OPTIONS 请求发送到服务器 而没有 Authorization header——因为 OPTIONS 检查是看是否可以发送。
  5. 服务器看到 OPTIONS 请求,但没有以表明它允许 Authorization 请求的方式响应它,而是用 401 拒绝它,因为它缺少 header.
  6. 您的浏览器期望 CORS 预检响应为 200 或 204,但却得到了 401 响应。所以你的浏览器就停在那里,永远不会尝试来自你的代码的 POST 请求。