JWT存入LocalStorage后用户授权失败,访问/users/me/提示未授权
问题排查与修复
核心问题1:JWT认证头格式不匹配
你的Django配置中,SIMPLE_JWT的AUTH_HEADER_TYPES设置为('JWT',),这意味着后端期望的Authorization头格式是JWT <token>,但前端代码里设置的是Bearer <token>,格式不匹配导致后端无法识别令牌,直接返回Unauthorized。
核心问题2:前端获取JWT令牌的字段错误
Djoser的/auth/jwt/create/接口返回的令牌字段是access(而非token),前端代码里用response.data.token获取的是undefined,相当于没传有效令牌。
修复步骤
1. 修正前端的令牌获取与头设置(LoginPage.jsx)
修改handleSubmit函数:
const handleSubmit = async (e) => { e.preventDefault(); try { const response = await axios.post('http://127.0.0.1:8000/auth/jwt/create/', { username: username, password: password }); // 正确获取access令牌 const accessToken = response.data.access; localStorage.setItem('token', accessToken); // 按照后端要求的格式设置Authorization头 axios.defaults.headers.common["Authorization"] = `JWT ${accessToken}`; setError(''); // 可添加调用用户信息接口的代码 // const userResponse = await axios.get('http://127.0.0.1:8000/auth/users/me/'); // console.log(userResponse.data); } catch (error) { setError('Invalid email or password'); } }
2. 可选:统一前后端的认证头类型(改用Bearer)
如果你更习惯用Bearer作为头前缀,也可以修改Django的settings.py:
SIMPLE_JWT = { 'AUTH_HEADER_TYPES': ('Bearer',), # 替换为Bearer 'ACCESS_TOKEN_LIFETIME': timedelta(days=2) }
这样前端的Bearer ${token}无需修改。
3. 补充:页面刷新后恢复认证头
当前代码只在登录时设置一次axios默认头,页面刷新后会丢失,建议在App初始化时从localStorage读取令牌并设置头:
在App.js中添加:
import axios from 'axios'; import React from 'react'; function App() { // 页面加载时恢复认证头 React.useEffect(() => { const token = localStorage.getItem('token'); if (token) { axios.defaults.headers.common["Authorization"] = `JWT ${token}`; // 或Bearer,匹配后端配置 } }, []); return ( <Router> <Routes> <Route exact path="/" element={<LoginPage />} /> </Routes> </Router> ); }
额外检查点
确认你的用户模型authorize.User的username字段确实对应登录时输入的邮箱,或者后端认证逻辑支持用邮箱作为用户标识。默认的Django ModelBackend会以username字段作为认证依据,若你的用户用邮箱登录,需确保username字段存储的是邮箱,或自定义认证后端支持邮箱登录。
内容的提问来源于stack exchange,提问作者Vansh_Chaudhary
相关产品推荐
相关产品推荐

