【问题标题】:401 error - JWT Token not found using fetch401 错误 - 使用 fetch 找不到 JWT 令牌
【发布时间】:2018-01-15 09:51:47
【问题描述】:

我是新手,主要是 javascript。 我正在对托管在 localhost:3000 上的 web 应用程序使用 react,后端使用 node.js 和 symfony 2.8,使用 apache 托管在 localhost:80 上,它公开了一个由 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

我迷路了。

【问题讨论】:

    标签: apache symfony http cors fetch-api


    【解决方案1】:

    您需要配置您的后端,以便它以 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. 您的浏览器期望 CORS 预检得到 200 或 204 响应,但得到的是 401 响应。因此,您的浏览器会停在那里,并且永远不会尝试来自您的代码的 POST 请求。

    【讨论】:

    • 好的,谢谢,现在说得通了。我尝试了您的解决方案,但没有解决问题。现在我明白了问题出在哪里,我认为 Symfony 的 NelmioCorsBundle 可以解决这个问题。有时间我会研究它,但现在我只是通过 GET 传递我的令牌。
    猜你喜欢
    • 2018-07-17
    • 2020-07-02
    • 2020-08-04
    • 2019-12-05
    • 2018-03-16
    • 1970-01-01
    • 2022-07-08
    • 2017-06-20
    • 2016-05-17
    相关资源
    最近更新 更多