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

React JS如何通过Fetch实现用户登录认证?

React + Fetch 实现正确的登录认证跳转逻辑

嘿,我看了你的代码,问题其实很明显——你现在不管登录请求成功与否,都会直接跳转到着陆页,而且你的fetchData方法还在使用硬编码的用户名密码,根本没用到输入框里的用户输入!下面我一步步帮你修改代码,实现仅当认证成功时才跳转的功能。

核心问题梳理

  1. onSubmit方法直接跳转:你在调用fetchData()后立刻执行了this.props.history.push('/landing'),完全没等登录请求返回结果,所以不管凭证对错都会跳转。
  2. 硬编码的请求参数:fetchData里的请求体用的是固定的username: 'myUserName',没有绑定输入框的state值。
  3. 多余的请求参数:请求体里加了Authorization字段,但这时候你还没拿到token,属于无效参数。

修改步骤及完整代码

第一步:修复fetchData方法,绑定用户输入并处理认证结果

我们要把请求参数换成state里的用户名和密码,同时在请求返回后判断是否认证成功,只有成功才跳转,失败则提示错误。

第二步:调整onSubmit方法,移除直接跳转逻辑

让onSubmit只负责触发登录请求,跳转逻辑交给fetch的成功回调处理。

完整修改后的代码

import React, { Component } from 'react';
import './Login.css';
import { withRouter } from 'react-router-dom';

class Login extends Component {
  constructor() {
    super();
    this.state = {
      data: [],
      username: "",
      password: "",
      token: "",
    };
  }

  componentDidMount() {
    // 登录是用户主动操作,页面加载时不需要发起请求,注释掉原调用
    // this.fetchData();
  }

  fetchData = () => {
    // 从state中获取用户输入的用户名和密码
    const { username, password } = this.state;
    
    fetch('http://theapi/api/auth', {
      method: 'POST',
      headers: {
        'Content-type': 'application/json',
      },
      // 传递用户输入的凭证,移除多余的Authorization参数
      body: JSON.stringify({ 
        username: username, 
        password: password 
      })
    })
    .then(results => {
      // 先检查HTTP状态码,2xx以外的状态码都视为认证失败
      if (!results.ok) {
        throw new Error('用户名或密码错误,请重试');
      }
      return results.json();
    })
    .then(data => {
      // 认证成功:保存token,清空输入框,跳转至着陆页
      this.setState({ 
        data: data, 
        token: data.token,
        username: "",
        password: ""
      });
      this.props.history.push('/landing');
    })
    .catch(error => {
      // 处理错误:提示用户,打印错误日志
      alert(error.message);
      console.error('登录失败:', error);
    });
  }

  change = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  };

  onSubmit = (e) =>{
    e.preventDefault(); // 阻止表单默认提交行为
    this.fetchData(); // 发起登录请求,跳转逻辑在fetch回调中处理
  };

  render() {
    console.log(this.state.data);
    return (
      <div>
        <div className="loginContainer">
          <h2>Member Login</h2>
          <form>
            <input 
              id="username" 
              name="username" 
              placeholder="User Name" 
              value={this.state.username} 
              onChange={e => this.change(e) } 
              className="form-control" 
            />
            <br />
            <input 
              id="password" 
              name="password" 
              type="password" 
              placeholder="Password" 
              value={this.state.password} 
              onChange={e => this.change(e) } 
              className="form-control" 
            />
            <br />
            <button onClick={e => this.onSubmit(e)} className="btn btn-primary">Submit</button>
          </form>
        </div>
      </div>
    );
  }
}

export default withRouter(Login);

额外说明

  • 我注释掉了componentDidMount里的this.fetchData(),因为登录应该是用户点击提交后才发起的,页面加载时不需要自动请求。
  • 在fetch的第一个then中,通过!results.ok判断HTTP状态码,即使返回JSON,只要状态码是401(未授权)或其他错误码,都会抛出错误进入catch分支。
  • 错误提示用了alert,你可以换成更友好的UI组件(比如在页面上显示错误文本)来提升用户体验。
  • 假设你的API返回的data中包含token字段,如果实际返回的字段名不同,记得修改data.token为对应的字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:02:22