React 实现 JWT 登录验证的最小可运行示例

下面是一个用 React 实现 JWT 登录验证的最小可运行示例,包含:

  • React 前端:登录、保存 Token、获取用户数据。
  • 模拟后端:用 mock API(你也可以接真后端)。

🧱 技术栈

  • React(使用 Vite)
  • axios 发送请求
  • localStorage 保存 JWT
  • 使用一个假的后端 API(模拟 JWT 认证)

🚀 最终效果

  1. 用户输入用户名和密码登录;
  2. 服务器返回 JWT;
  3. 前端保存 JWT;
  4. 访问受保护的用户信息页时,携带 JWT 请求头访问。

🛠️ 第一步:初始化项目

bash 复制代码
npm create vite@latest jwt-demo -- --template react
cd jwt-demo
npm install
npm install axios

📁 目录结构

复制代码
src/
├─ App.jsx
├─ pages/
│  ├─ Login.jsx
│  └─ Profile.jsx
├─ api.js
└─ main.jsx

✏️ 第二步:代码实现

🔹 src/api.js(模拟 API)

js 复制代码
import axios from 'axios';

const mockToken = "fake-jwt-token-123456";

export async function login(username, password) {
  if (username === 'admin' && password === '123456') {
    return { token: mockToken };
  } else {
    throw new Error('登录失败');
  }
}

export async function getProfile(token) {
  if (token === mockToken) {
    return { username: 'admin', email: 'admin@example.com' };
  } else {
    throw new Error('无效Token');
  }
}

🔹 src/pages/Login.jsx

js 复制代码
import { useState } from 'react';
import { login } from '../api';

export default function Login({ onLogin }) {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const handleLogin = async () => {
    try {
      const res = await login(username, password);
      localStorage.setItem('token', res.token);
      onLogin();
    } catch (e) {
      setError('用户名或密码错误');
    }
  };

  return (
    <div>
      <h2>登录</h2>
      <input placeholder="用户名" value={username} onChange={e => setUsername(e.target.value)} /><br />
      <input type="password" placeholder="密码" value={password} onChange={e => setPassword(e.target.value)} /><br />
      <button onClick={handleLogin}>登录</button>
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}

🔹 src/pages/Profile.jsx

js 复制代码
import { useEffect, useState } from 'react';
import { getProfile } from '../api';

export default function Profile() {
  const [profile, setProfile] = useState(null);
  const [error, setError] = useState('');

  useEffect(() => {
    const token = localStorage.getItem('token');
    getProfile(token)
      .then(data => setProfile(data))
      .catch(err => setError('认证失败,请重新登录'));
  }, []);

  if (error) return <p>{error}</p>;
  if (!profile) return <p>加载中...</p>;

  return (
    <div>
      <h2>用户信息</h2>
      <p>用户名: {profile.username}</p>
      <p>邮箱: {profile.email}</p>
    </div>
  );
}

🔹 src/App.jsx

js 复制代码
import { useState } from 'react';
import Login from './pages/Login';
import Profile from './pages/Profile';

export default function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(!!localStorage.getItem('token'));

  const handleLogout = () => {
    localStorage.removeItem('token');
    setIsLoggedIn(false);
  };

  return (
    <div>
      {isLoggedIn ? (
        <>
          <Profile />
          <button onClick={handleLogout}>退出登录</button>
        </>
      ) : (
        <Login onLogin={() => setIsLoggedIn(true)} />
      )}
    </div>
  );
}

✅ 运行

bash 复制代码
npm run dev

访问 http://localhost:5173,输入:

  • 用户名:admin
  • 密码:123456

然后你将登录并看到用户信息页,JWT 被保存在 localStorage


后面重启后就不用再输入密码了

相关推荐
FreeTinker5 小时前
HTML本地存储技术解析:localStorage与sessionStorage的原理、差异与应用场景
前端·html
qq_452396235 小时前
第十二篇:《全链路监控与可观测性:前端错误追踪与性能分析》
前端
wangruofeng6 小时前
Phosphor Icons 官网源码拆解:URL 即存储、水波动画与 7362 Star 图标库的架构实践
前端·架构·github
BigTopOne6 小时前
WebRTC Native / Android 开发学习资源整理
前端
excel7 小时前
nuxt 3 升级 nuxt 4 报错之 hasInjectionContext
前端
何以解忧,唯有..8 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
软件聚导航8 小时前
「聚小软 AI 助手」技术升级:从数据库检索到 RAG 知识库问答
前端·数据库·mysql·微信小程序·小程序·ai编程·rag
恋猫de小郭9 小时前
看懂大模型架构术语,帮助你理解目前常见的大模型开源架构
前端·人工智能·ai编程
yma169 小时前
通过提示词实现GitHub Pages 和 Nginx 双部署竟然这么简单?
前端
前端 贾公子9 小时前
第09章:上下文与记忆 (2)
java·服务器·前端