You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目Axios调用用户搜索接口返回401未授权问题求助

React Axios请求带Authorization头仍返回401的解决方案

问题说明

开发React项目的用户搜索功能,通过Axios发起GET请求/api/user/allusers并携带search参数,空输入校验功能正常,但携带token请求时始终返回401 (Unauthorized)。前端已在请求头中添加Authorization: Bearer ${user.token},但后端认证中间件未识别到token。

代码片段

前端搜索请求代码

const handleSearch = async () => {
  if (!search) {
    toast({
      title: "Please Enter something in search",
      status: "warning",
      duration: 5000,
      isClosable: true,
      position: "top-left",
    });
    return;
  }

  try {
    setLoading(true);
    const config = {
      headers: {
        "Content-type": "application/json",
        Authorization: `Bearer ${user.token}`,
      },
      withCredentials: true,
    };
    const { data } = await axios.get(`http://localhost:5000/api/user/allusers?search=${search}`, config);
    setLoading(false);
    setSearchResult(data);
  } catch (error) {
    toast({
      title: "Error Occured!",
      description: "Failed to Load the Search Results",
      status: "error",
      duration: 5000,
      isClosable: true,
      position: "bottom-left",
    });
    console.log(error);
  }
};

后端认证中间件代码

const isAuthenticatedUser = asyncHandler(async (req, res, next) => {
  const { token } = req.cookies;

  if (!token) {
    return next(new ErrorHandler("Please Login to access this resource", 401));
  }

  const decodedData = jwt.verify(token, process.env.JWT_SECRET);
  req.user = await User.findById(decodedData.id);

  if (!req.user) {
    return next(new ErrorHandler("User does not exist", 401));
  }

  next();
});

module.exports = isAuthenticatedUser;

问题根源

后端中间件仅从req.cookies中读取token,但前端是将token放在Authorization请求头里,两者获取token的方式不匹配,导致后端检测不到有效token,返回401。

解决方法

方法一:修改后端中间件,支持从Authorization头获取token

让中间件优先检查请求头的Authorization字段,若不存在再从cookie获取,兼容两种传参方式:

const isAuthenticatedUser = asyncHandler(async (req, res, next) => {
  let token;

  // 从Authorization Bearer头提取token
  if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
    token = req.headers.authorization.split(' ')[1];
  }
  // 头中无token则尝试从cookie获取
  else if (req.cookies.token) {
    token = req.cookies.token;
  }

  if (!token) {
    return next(new ErrorHandler("Please Login to access this resource", 401));
  }

  const decodedData = jwt.verify(token, process.env.JWT_SECRET);
  req.user = await User.findById(decodedData.id);

  if (!req.user) {
    return next(new ErrorHandler("User does not exist", 401));
  }

  next();
});

方法二:修改前端,将token存入cookie

如果后端设计为依赖cookie传递token,前端登录成功后将token写入cookie,请求时通过withCredentials: true自动携带:

// 登录成功后设置cookie(示例使用js-cookie库,需先安装:npm install js-cookie)
import Cookies from 'js-cookie';

// 假设登录接口返回user对象包含token
Cookies.set('token', user.token, { 
  expires: 7, // 有效期7天
  secure: process.env.NODE_ENV === 'production', // 生产环境启用secure
  sameSite: 'strict'
});

// 搜索请求中无需手动添加Authorization头,只需保留withCredentials
const handleSearch = async () => {
  // ...空输入校验逻辑不变

  try {
    setLoading(true);
    const config = {
      withCredentials: true, // 自动携带cookie
    };
    const { data } = await axios.get(`http://localhost:5000/api/user/allusers?search=${search}`, config);
    setLoading(false);
    setSearchResult(data);
  } catch (error) {
    // ...错误处理逻辑不变
  }
};

额外注意事项

  1. 跨域配置:后端需开启CORS支持凭证,以Express为例:
    const cors = require('cors');
    app.use(cors({
      origin: 'http://localhost:3000', // 前端域名
      credentials: true
    }));
    
  2. token有效性:确保前端传入的token未过期,且后端JWT签名密钥process.env.JWT_SECRET与生成token时一致。

内容的提问来源于stack exchange,提问作者Deepshikha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 09:33:20