为啥在 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 后端获取调用?
在 Heroku 上使用 React、Axios 访问内部 API
在 React 中通过 axios 调用 API(使用自签名证书)时出现 CORS 问题