我对以下代码有一个问题,这让我发疯。
简而言之,我想做的是:
- 将 sessionStorage 中保存的 JWT 令牌保存为登录成功时的状态。
- 在状态中保存布尔值 isTokenValid。
- 通过对 /api/validateToken 端点的 GET 请求检查令牌是否有效并相应地设置 isTokenValid。
- 如果令牌有效 (isTokenValid = true) --> 显示仪表板
- 如果令牌无效(TokenValid = false)--> 显示错误页面
App.jsx
import './styles/Reset.css';
import './styles/App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import axios from 'axios';
import Home from './components/Home';
import Header from './components/Header';
import Footer from './components/Footer';
import Login from './components/Login';
import Signup from './components/Signup';
import Dashboard from './components/Dashboard';
import FailedAuth from './components/FailedAuth';
function App() {
const [token, setToken] = React.useState(sessionStorage.getItem('token'));
const [isTokenValid, setIsTokenValid] = React.useState(false);
const [loading, setLoading] = React.useState(true);
async function validateToken() {
try {
const response = await axios.get('http://localhost:5000/api/validateToken', {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.status === 200) {
setIsTokenValid(true);
} else {
setIsTokenValid(false);
}
} catch (error) {
setIsTokenValid(false);
} finally {
setLoading(false);
}
}
React.useEffect(() => {
async function fetchData() {
if (token) {
await validateToken();
}
}
fetchData();
});
if (loading) {
return (
<div className="loading">
<div className="spinner-border text-primary" role="status">
<span className="visually-hidden">Loading...</span>
</div>
</div>
);
}
return (
<Router>
<Routes>
<Route path="/login/*" element={
<>
<Header type="auth" />
<Login />
</>
}
/>
<Route path="/signup/*" element={
<>
<Header type="auth" />
<Signup />
</>
}
/>
<Route path="/*" element={
<>
<Header type="home" />
<Home />
<Footer />
</>
}
/>
<Route path="/dashboard/*" element={
<>
{isTokenValid ? <Dashboard /> : <FailedAuth />}
</>
}
/>
</Routes>
</Router>
);
}
export default App;
服务器.js
app.get('/api/validateToken', passport.authenticate('jwt', { session: false }), (req, res) => {
try {
res.status(200).json({ message: 'Token is valid' });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
服务器完美地处理身份验证,并且 JWT 令牌已正确分配。
我的问题恰恰在于 isTokenValid 条件下的路由渲染。
当用户登录时,它会呈现到仪表板,即使令牌有效,它也会立即显示
令牌过期后,总是显示
我认为这是一个同步问题,但我不确定(我对React还是新手,这是我的第一个项目)。
有人可以帮助我吗?这样当我发现自己面临同样的情况时,我知道如何行事。
解决方案
[token]
添加到 useEffect 挂钩作为依赖项数组。
useEffect(() => {
async function fetchData() {
if (token) {
await validateToken();
}
}
fetchData();
}, [token]);