JWT认证后续操作与私有路由创建求助:Token获取及携带
解决JWT认证后续流程问题
1. 获取并存储Token
你的前端已经能在控制台拿到返回的Token,只需从响应中提取并存储到本地(推荐用localStorage,刷新页面也不会丢失)。修改Login.js中的handleSubmit函数:
const handleSubmit = () => { fetch('http://localhost:3001/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({username, password}) }) .then((response) => response.json()) .then((res) => { if (res.token) { // 存储Token到localStorage localStorage.setItem('authToken', res.token); // 登录成功后跳转到私有页面(比如dashboard) window.location.href = '/dashboard'; } else { console.log(res.message || '登录失败'); } }) .catch(err => console.error('请求错误:', err)); }
另外,密码输入框建议把type改成password,避免明文显示:
<input className="inputlogin" type="password" placeholder="Password..." onChange={(e) => { setPassword(e.target.value) }}></input>
2. 发起请求时携带Token到请求头
后续访问需要认证的后端接口时,要在请求头中加入Authorization字段,格式为Bearer <你的Token>。可以封装一个通用的请求函数,避免重复代码:
// 通用请求函数 const fetchWithAuth = (url, options = {}) => { const token = localStorage.getItem('authToken'); const headers = { 'Content-Type': 'application/json', ...options.headers, ...(token && { Authorization: `Bearer ${token}` }) }; return fetch(url, { ...options, headers }); }; // 使用示例:访问私有接口 const fetchPrivateData = () => { fetchWithAuth('http://localhost:3001/private-endpoint') .then(res => res.json()) .then(data => console.log('私有数据:', data)) .catch(err => console.error('请求失败:', err)); };
后端需要添加Token验证中间件
为了确保只有携带有效Token的请求能访问私有接口,需要在后端添加一个验证中间件:
// 导入jwt(确保你已经安装并导入) const jwt = require('jsonwebtoken'); // Token验证中间件 const authenticateToken = (req, res, next) => { // 从请求头获取Authorization字段 const authHeader = req.headers['authorization']; // 提取Token(格式是Bearer <token>,所以分割取第二部分) const token = authHeader && authHeader.split(' ')[1]; if (!token) { return res.status(401).json('Acesso negado: Token não fornecido'); } // 验证Token有效性 jwt.verify(token, SECRET, (err, user) => { if (err) { return res.status(403).json('Token inválido'); } // 将用户信息挂载到req对象,后续接口可以直接使用 req.user = user; next(); // 继续执行后续路由逻辑 }); }; // 使用中间件保护私有路由 app.get('/private-endpoint', authenticateToken, (req, res) => { // 这里可以通过req.user.id获取登录用户的ID res.json({ message: 'Acesso permitido', userId: req.user.id }); });
3. 创建React私有路由
使用react-router-dom(假设是v6版本)创建私有路由组件,未登录用户无法访问私有页面:
第一步:创建PrivateRoute组件
import { Navigate, Outlet } from 'react-router-dom'; export default function PrivateRoute() { // 检查localStorage中是否存在Token const isAuthenticated = !!localStorage.getItem('authToken'); // 已认证则渲染子路由,否则跳转到登录页 return isAuthenticated ? <Outlet /> : <Navigate to="/login" />; }
第二步:配置路由
在你的主路由文件(比如App.js)中使用私有路由包裹需要保护的页面:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Login from './Login'; import Dashboard from './Dashboard'; // 你的私有页面组件 import PrivateRoute from './PrivateRoute'; function App() { return ( <Router> <Routes> {/* 公开路由 */} <Route path="/login" element={<Login />} /> {/* 私有路由:所有子路由都需要认证才能访问 */} <Route element={<PrivateRoute />}> <Route path="/dashboard" element={<Dashboard />} /> {/* 其他私有页面都放在这里 */} </Route> {/* 默认路由跳转 */} <Route path="/" element={<Navigate to="/login" />} /> </Routes> </Router> ); } export default App;
内容的提问来源于stack exchange,提问作者Pedro Martins
相关产品推荐
相关产品推荐

