为啥在 React 中,我的 axios API 调用有 Authorization Header,其中包含 Bearer <token> 但未被授权并给出 401 错误

Posted

技术标签:

【中文标题】为啥在 React 中,我的 axios API 调用有 Authorization Header,其中包含 Bearer <token> 但未被授权并给出 401 错误【英文标题】:Why in React, my axios API call has Authorization Header which contains Bearer <token> but not being authorized and gives 401 error为什么在 React 中,我的 axios API 调用有 Authorization Header,其中包含 Bearer <token> 但未被授权并给出 401 错误 【发布时间】:2019-08-14 06:51:06 【问题描述】:

我正在对我的 php API 进行 axios 调用(当将有效令牌发送回 API 服务器时,它会显示用户数据)并在请求标头(连同 Bearer 作为前缀)和网络选项卡中发送有效的 jwt 令牌它表明我的令牌正在标头中发送,但它仍然给我 401 错误并返回“jwt 为空”的 API 错误消息...

我用于获取用户数据的 API(当提供有效令牌时)位于 http://localhost/Auth/api/validate.php

客户端在http://localhost:3000

这个 API 在 php 中并且在 Postman 上运行得非常好。但是当我在反应中调用它时给了我 401(未经授权)。我搜索了这个错误,每个人都说你应该在请求标头中有令牌,我确实有它,但它没有被服务器读取,服务器认为它为空,所以向我发送未经授权的错误。请帮帮我!!!!!!

这里是 axios API 调用:

e.preventDefault();
const token = localStorage.getItem("jwttoken");

 axios.post('http://localhost/Auth/api/validate.php',token, 
headers: 
'Authorization' : 'Bearer '+token,
  'Accept': 'application/json, text/plain, */*',
   'Content-Type': 'application/json'
       )

.then(response =>

console.log(response.data);
console.log(response);
return response;
)
  .catch(error => 
  if (error) 
    console.log("Sorry.....Error");  
    );

响应标头

>  Request URL: http://localhost/Auth/api/validate.php 
>  Request Method: POST 
>  Remote Address: [::1]:80 
>  Status Code: 401 Unauthorized
>  Referrer Policy: no-referrer-when-downgrade
> Accept: application/json; charset=UTF-8, */* 
> Access-Control-Allow-Credentials: true 
> Access-Control-Allow-Headers: Content-Type, Accept,  X-Auth-Token, Origin,  Authorization, Client-Security-Token, Accept-Encoding, X-Requested-With
> Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD, OPTIONS
> Access-Control-Allow-Origin: * 
> Access-Control-Exposed-Header: true
> Authorization Access-Control-Max-Age: 33600
>  Connection: Keep-Alive
> Content-Length: 34 
> Content-Type: application/json; charset=UTF-8, */*
> Date: Sat, 23 Mar 2019 12:33:00 GMT Keep-Alive: timeout=5, max=99
> Server: Apache/2.4.29 (Win32) OpenSSL/1.1.0g PHP/7.2.3 X-Powered-By:
> PHP/7.2.3

请求标头:

> Provisional headers are shown Accept: application/json, text/plain, */*
>Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7IlZlbmRvcklEIjoiNDQiLCJDb21wYW55TmFtZSI6IlRhZGEiLCJDb250YWN0UGVyc29uIjoiVGFkYSIsIkNvbnRhY3RObyI6Ijg3ODciLCJlbWFpbCI6InRhZGFAZ21haWwuY29tIn19.YmaD_VjMKYifWXd4DsRXRodVDpBy8zASLnIfgquCwLI

> Content-Type: application/json 
> Origin: http://localhost:3000 
> Referer: http://localhost:3000/profile 
> User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/72.0.3626.121 Safari/537.36


> Request Payload: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7IlZlbmRvcklEIjoiNDQiLCJDb21wYW55TmFtZSI6IlRhZGEiLCJDb250YWN0UGVyc29uIjoiVGFkYSIsIkNvbnRhY3RObyI6Ijg3ODciLCJlbWFpbCI6InRhZGFAZ21haWwuY29tIn19.YmaD_VjMKYifWXd4DsRXRodVDpBy8zASLnIfgquCwLI

这是我的 API validate.php

<?php
// required headers//
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true");
header("Content-Type: application/json; charset=UTF-8, */*");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Max-Age: 33600");
header("Content-Length: 144");
header("Accept: application/json; charset=UTF-8, */*");
header("Access-Control-Exposed-Header: Authorization");
header("Access-Control-Allow-Headers: Content-Type, Accept,  X-Auth-Token, Origin,  Authorization,  Client-Security-Token, Accept-Encoding, X-Requested-With");


// required to decode bbbb
include_once 'config/core.php';
include_once 'libs/php-jwt-master/php-jwt-master/src/BeforeValidException.php';
include_once 'libs/php-jwt-master/php-jwt-master/src/ExpiredException.php';
include_once 'libs/php-jwt-master/php-jwt-master/src/SignatureInvalidException.php';
include_once 'libs/php-jwt-master/php-jwt-master/src/JWT.php';
use \Firebase\JWT\JWT;

// get posted data
$data = json_decode(file_get_contents("php://input"));

// get jwt
$jwt=isset($data->jwt) ? $data->jwt : "";

// if jwt is not empty
if($jwt)

    // if decode succeed, show user details
    try 
        // decode jwt
        $decoded = JWT::decode($jwt, $key, array('HS256'));

        // set response code
        http_response_code(200);

        // show user details
        echo json_encode(array(
            "message" => "Access granted.",
            "data" => $decoded->data
        ));

    

        // if decode fails, it means jwt is invalid
    catch (Exception $e)

        // set response code
        http_response_code(401);

        // tell the user access denied  & show error message
        echo json_encode(array(
            "message" => "Access denied. Decode fails",
            "error" => $e->getMessage()
        ));
    


// show error message if jwt is empty
//gggg
else

    // set response code
    http_response_code(401);

    // tell the user access denied
    echo json_encode(array("message" => "Access denied. Empty"));

?>

编辑 我也尝试发送不带“Bearer”前缀的令牌,但它没有用。在 Postman 上,我向我的服务器 API 发送一个发布请求(在正文中),如下所示(效果很好):


"jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7IlZlbmRvcklEIjoiNTkiLCJDb21wYW55TmFtZSI6IkVub3VnaCIsIkNvbnRhY3RQZXJzb24iOiJlbm91Z2giLCJDb250YWN0Tm8iOiIzNDM0NCIsImVtYWlsIjoiZUBnbWFpbC5jb20ifX0.o4V6zu8AFBAMoJgRe_jvMoByDK3yDEiF_pxW4ttqpYQ"

【问题讨论】:

您的浏览器是否发送了预检选项请求?检查您的浏览器网络标签 你是从正文还是标题中读取 jwt 令牌? @AmstelD'Almeida 是的,它正在发送一个预检选项,我通过将 OPTIONS 请求重定向到返回 200 状态 OK 的空白页面解决了这个问题,然后它发送了它显示的我的实际 POST 请求401 错误 邮递员中的@JibinMathews 我从正文选项卡发送了令牌(就像我在编辑中提到的那样)所以我是否应该在进行 API axios 调用时也将令牌发送到正文中?顺便说一句,非常感谢您的回复。 @YellowMinion 查看您的 php 代码,JWT 令牌应该在正文中作为 json 而不是标头发送。 【参考方案1】:

php 代码在正文中需要 JWT 令牌。令牌应采用 JSON 格式,如下所示。

const token = localStorage.getItem("jwttoken");

 axios.post('http://localhost/Auth/api/validate.php',"jwt":token, 
headers: 
  'Accept': 'application/json, text/plain, */*',
   'Content-Type': 'application/json'
       )

.then(response =>

console.log(response.data);
console.log(response);
return response;
)
  .catch(error => 
  if (error) 
    console.log("Sorry.....Error");  
    );

【讨论】:

天啊.. 它奏效了。非常感谢您的回复和帮助! 您能帮我了解如何在我的客户端 REACT 界面上显示此访问的数据(在控制台上)吗?再次感谢 @YellowMinion 可以使用 response.data.message 访问消息,使用 response.data.data 可以访问 jwt 对象

以上是关于为啥在 React 中,我的 axios API 调用有 Authorization Header,其中包含 Bearer <token> 但未被授权并给出 401 错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 axios 使用 React.useEffect 一遍又一遍地从 Rails 后端获取调用?

为啥我的 Axios 实例没有在捕获的错误中返回响应?

在 Heroku 上使用 React、Axios 访问内部 API

在 React 中通过 axios 调用 API(使用自签名证书)时出现 CORS 问题

使用 React 和 Axios 从 Express API 下载文件

尝试使用 axios 在 React/Phoenix 应用程序中进行 API 调用(使用早午餐)