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

React登录认证控制器异常:无法从服务器获取数据求助

问题描述

我是React新手,在使用axios和jsonwebtoken实现服务器数据获取与路由功能时遇到登录认证控制器失效的问题。浏览器控制台未发现报错,但网站始终无响应,请求协助排查并修复。


相关代码

AuthController.js

import UserModel from "../Models/userModel.js";
import bcrypt from 'bcrypt'
import jwt from "jsonwebtoken";


// Registering a new User
export const registerUser = async (req, res) => {
  const { username, password, firstname, lastname } = req.body
  const salt = await bcrypt.genSalt(10)
  const hashedPass = await bcrypt.hash(password, salt)
  // req.body.passowrd = hashedPass

  const newUser = new UserModel({
    username,
    password: hashedPass,
    firstname,
    lastname
  })

  try {
    // check username
    const oldUser = await UserModel.findOne({ username })
    if (oldUser) {
      return res.status(400).json({ message: "The username is already exist" })
    }

    const user = await newUser.save()
    const token = jwt.sign({
      username: user.username, id: user._id
    }, process.env.JWT_KEY, { expiresIn: '1h' })

    res.status(200).json({ user, token })
  } catch (error) {
    res.status(500).json({ message: error.message })
  }
};


// login user 

export const loginUser = async (req, res) => {
  const { username, password } = req.body;

  try {
    const user = await UserModel.findOne({ username: username })

    if (user) {
      const validity = await bcrypt.compare(password, user.password);

      validity ? res.status(200).json(user) : res.status(400).json("Wrong Password")
      const token = jwt.sign(
        { username: user.username, id: user._id },
        process.env.JWTKEY,
        { expiresIn: "1h" }
      );
      res.status(200).json({ user, token });
    } else {
      res.status(404).json("User not found");
    }

  } catch (error) {
    res.status(500).json({ message: error.message })
  }
}

Auth Reducer

const authReducer = (state = { auhtData: null, loading: false, error: false }, action) => {
  switch (action.type) {
    case "AUTH_START": return { ...state, loading: true, error: false };
    case "AUTH_SUCCES":
      localStorage.setItem("profile", JSON.stringify({ ...action?.data }))
      return { ...state, authData: action.data, loading: false, error: false };
    case "AUTH_FAIL": return { ...state, loading: false, error: true }
    default: return state;
  }
}

export default authReducer

Auth Action

import * as AuthApi from '../api/AuthRequests.js';

export const logIn = (formData) => async (dispatch) => {
  dispatch({ type: "AUTH_START" });
  try {
    const { data } = await AuthApi.logIn(formData);
    dispatch({ type: "AUTH_SUCCESS", data: data });
  } catch (error) {
    console.log(error);
    dispatch({ type: "AUTH_FAIL" });
  }
};

export const signUp = (formData) => async (dispatch) => {

  dispatch({ type: "AUTH_START" })
  try {
    const { data } = await AuthApi.signUp(formData)
    dispatch({ type: "AUTH_SUCCES", data: data })

  } catch (error) {
    console.log(error)
    dispatch({ type: "AUTH_FAIL" })
  }
}

Auth Request for API

import axios from 'axios'


const API = axios.create({ baseURL: "http://localhost:5000" });

export const logIn = (formData) => API.post('/auth/login', formData);

export const signUp = (formData) => API.post('/auth/register', formData);

index.js

import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import dotenv from 'dotenv';
import cors from 'cors'
import AuthRoute from './Routes/AuthRoute.js'
import UserRoute from './Routes/UserRoute.js'
import PostRoute from './Routes/PostRoute.js'


//Routes
const app = express();


// Middleware
app.use(bodyParser.json({
  limit: '30mb', extended: true,
}))

app.use(bodyParser.urlencoded({
  limit: '30mb', extended: true,
}))

app.use(cors())

dotenv.config();


mongoose.connect(process.env.MONGO_DB, { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => app.listen(process.env.PORT, () => console.log(`Listening to ${process.env.PORT}`)))
  .catch((error) => console.log(error));


// usage of routes
app.use('/auth', AuthRoute)
app.use('/user', UserRoute)
app.use('/post', PostRoute)

问题排查与修复方案

1. 登录控制器重复响应(核心问题)

loginUser函数中,密码验证后已发送一次HTTP响应,但后续又再次发送响应。HTTP规范要求一个请求只能对应一个响应,重复响应会导致服务器内部报错,请求挂起无返回。

修复代码:

export const loginUser = async (req, res) => {
  const { username, password } = req.body;

  try {
    const user = await UserModel.findOne({ username: username })

    if (!user) {
      return res.status(404).json("User not found");
    }

    const validity = await bcrypt.compare(password, user.password);
    if (!validity) {
      return res.status(400).json("Wrong Password");
    }

    // 统一环境变量名,与注册逻辑保持一致
    const token = jwt.sign(
      { username: user.username, id: user._id },
      process.env.JWT_KEY,
      { expiresIn: "1h" }
    );
    res.status(200).json({ user, token });

  } catch (error) {
    res.status(500).json({ message: error.message })
  }
}

2. 环境变量名不统一

注册逻辑使用process.env.JWT_KEY,但登录逻辑误写为process.env.JWTKEY,导致生成token失败,需统一环境变量名。

3. Reducer与Action的拼写错误

  • Reducer初始状态中auhtData拼写错误,应为authData
  • Action中注册成功的type为AUTH_SUCCES(少写一个s),与登录逻辑的AUTH_SUCCESS不统一,需修正为一致的AUTH_SUCCESS

修复后的Reducer:

const authReducer = (state = { authData: null, loading: false, error: false }, action) => {
  switch (action.type) {
    case "AUTH_START": return { ...state, loading: true, error: false };
    case "AUTH_SUCCESS":
      localStorage.setItem("profile", JSON.stringify({ ...action?.data }))
      return { ...state, authData: action.data, loading: false, error: false };
    case "AUTH_FAIL": return { ...state, loading: false, error: true }
    default: return state;
  }
}

修复后的Action注册逻辑:

export const signUp = (formData) => async (dispatch) => {
  dispatch({ type: "AUTH_START" })
  try {
    const { data } = await AuthApi.signUp(formData)
    dispatch({ type: "AUTH_SUCCESS", data: data })
  } catch (error) {
    console.log(error.response?.data || error.message);
    dispatch({ type: "AUTH_FAIL" })
  }
}

4. 错误日志优化

在Action的catch块中,打印error.response?.data可以获取服务器返回的具体错误信息,方便调试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 20:25:16