React前端登录报参数不足和400错误,后端Basic验证正常如何解决
问题根因与修复方案
根因梳理
- 变量覆盖导致认证信息为空:在
submitHandler函数内部你重新声明了赋值为空字符串的userID和password变量,直接覆盖了组件state中存储的用户输入的账号密码,最终请求携带的是空白的认证信息,触发后端400错误。 - axios认证配置字段错误:axios官方的
auth配置要求传入username和password两个属性,你传入的是自定义字段userID,无法被正确识别生成符合要求的Basic认证头。 - localStorage调用参数缺失:
localStorage.setItem()方法要求传入「存储键名」和「存储值」两个必填参数,你仅传入了序列化后的结果,缺少键名,所以触发了参数不足的TypeError。 - 异步请求逻辑错误:你给
submitHandler加了async修饰,但没有await等待axios请求执行完成,导致拿到的result是处于pending状态的Promise对象,无法正常存储响应结果。 - 认证配置冗余:同时手动构造Basic认证头和传入axios的
auth配置项,属于重复配置,可能引发不必要的解析冲突。
修复后的submitHandler代码
const submitHandler = async (e) => { e.preventDefault(); try { // 直接使用state中的用户输入,不要重新声明同名变量覆盖 const url = 'http://localhost:8080/authenticate/'; // 不需要额外传body数据,后端从认证头取信息的话可以省略data参数 const response = await axios.post(url, {}, { withCredentials: true, // 直接用axios的auth配置,会自动生成正确的Basic认证头,不用手动编码 auth: { username: userID, password: password } }); console.log('Authenticated'); // 从响应头/响应体拿后端返回的jwt token,匹配后端返回逻辑即可 const token = response.headers.authorization || response.data; // 补全localStorage的键名参数 localStorage.setItem('userInfo', JSON.stringify({ token, userID })); // 登录成功跳转首页 history.push('/'); } catch(error) { console.error('Error on Authentication', error); } console.log(userID, password); }
手动构造认证头的适配写法
如果你不想用axios内置的auth配置,需要手动构造认证头的话,删除auth配置项,保留手动编码逻辑即可:
const submitHandler = async (e) => { e.preventDefault(); try { const token = Buffer.from(`${userID}:${password}`, 'utf8').toString('base64'); const url = 'http://localhost:8080/authenticate/'; const response = await axios.post(url, {}, { withCredentials: true, headers: { Authorization: `Basic ${token}` } }); // 后续存储、跳转逻辑同上 const token = response.headers.authorization || response.data; localStorage.setItem('userInfo', JSON.stringify({ token, userID })); history.push('/'); } catch(error) { console.error('Error on Authentication', error); } }
内容的提问来源于stack exchange,提问作者basics_typer
相关产品推荐
相关产品推荐

