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

时间:2017-08-08 01:28:50

标签: apache symfony http cors fetch-api

我是新手做出反应,主要是对javascript。 我正在使用localhost:3000上的web应用程序使用node.js和symfony 2.8作为我的后端,托管在localhost:80上使用apache,暴露了一个用lexik和fos用户保护的api。 在确保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)

这使我在预检请求的答案标题中出现以下错误:

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);

如果我理解的话,它不能是Lexik JWT Token not found中描述的apache错误:任何symfony 2.8项目的根目录下的默认.htaccess包括:

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

我检查过并启用了mod_rewrite。

以下是Chrome中报告的标题:

**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

我迷路了。

1 个答案:

答案 0 :(得分:0)

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

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

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

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

原因是因为这里发生的是:

  1. 您的代码告诉您的浏览器,它希望使用Authorization标题发送请求。
  2. 您的浏览器说,好的,带有Authorization标头的请求要求我执行CORS预检OPTIONS,以确保服务器允许带有该标头的请求。
  3. 您的浏览器会将OPTIONS请求发送到服务器,而不会显示Authorization标题 - 因为OPTIONS检查的全部目的是确定它是否正常发送它。
  4. 服务器看到OPTIONS请求,但不会以指示允许Authorization请求的方式对其进行响应,而是拒绝使用401,因为它缺少该标头。
  5. 您的浏览器需要200或204的CORS预检响应,而是获得401响应。因此,您的浏览器就会停在那里,并且永远不会尝试代码中的POST请求。