更新用户资料后axiosInstance报Invalid token specified错误排查
排查与解决「Invalid token specified」问题
1. 检查axiosInstance的token动态获取逻辑
确保axios请求拦截器每次请求都从最新状态中获取token,而非初始化时固定赋值。错误示例是初始化时一次性读取token,后续状态更新后无法同步:
// 错误写法:初始化时读取一次token,后续不会更新 const userInfo = JSON.parse(localStorage.getItem('userInfo')); const axiosInstance = axios.create({ baseURL: 'http://localhost:8000/api/', headers: { Authorization: userInfo ? `Bearer ${userInfo.access}` : '' } });
正确写法:通过请求拦截器实时获取最新token(从Redux store或localStorage):
import axios from 'axios'; import store from '../store'; const axiosInstance = axios.create({ baseURL: 'http://localhost:8000/api/', }); axiosInstance.interceptors.request.use( (config) => { // 每次请求都从Redux store取最新的用户信息 const { userInfo } = store.getState().userLogin; if (userInfo?.access) { config.headers.Authorization = `Bearer ${userInfo.access}`; } return config; }, (error) => Promise.reject(error) );
2. 确认用户更新后token是否需要同步更新
前端侧:updateUserProfileAction需同步更新状态中的token
如果后端在用户资料更新(尤其是密码修改)后返回新的JWT token,前端必须将新token同步到Redux store和localStorage,否则后续请求会使用旧的失效token:
export const updateUserProfile = (userData) => async (dispatch, getState) => { try { dispatch({ type: USER_UPDATE_PROFILE_REQUEST }); const { userLogin: { userInfo } } = getState(); const config = { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${userInfo.access}` } }; const { data } = await axiosInstance.put('/users/profile/', userData, config); // 更新用户详情状态的同时,同步更新登录状态的token dispatch({ type: USER_UPDATE_PROFILE_SUCCESS, payload: data }); dispatch({ type: USER_LOGIN_SUCCESS, payload: data }); localStorage.setItem('userInfo', JSON.stringify(data)); } catch (err) { dispatch({ type: USER_UPDATE_PROFILE_FAIL, payload: err.response?.data.detail || err.message }); } };
后端侧:检查用户更新是否触发token失效
如果用户更新了密码,Django Simple JWT默认会使旧token失效(JWT包含用户密码哈希校验)。此时后端需:
- 在更新接口返回新的access/refresh token
- 或提示用户重新登录
示例后端视图:
from rest_framework.response import Response from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated from rest_framework_simplejwt.tokens import RefreshToken from .serializers import UserSerializer @api_view(['PUT']) @permission_classes([IsAuthenticated]) def update_user_profile(request): user = request.user serializer = UserSerializer(user, data=request.data, partial=True) if serializer.is_valid(): serializer.save() # 更新密码后生成新token返回 refresh = RefreshToken.for_user(user) return Response({ **serializer.data, 'access': str(refresh.access_token), 'refresh': str(refresh) }) return Response(serializer.errors, status=400)
3. 验证getUserDetailsAction的调用时机
确保getUserDetailsAction在updateUserProfileAction成功完成后再调用,避免在token未更新前发起请求。示例profile_screen.js逻辑:
// 正确写法:利用Redux状态判断更新完成后调用 useEffect(() => { if (userUpdateProfileSuccess) { dispatch(getUserDetails('profile')); // 重置成功状态 dispatch({ type: USER_UPDATE_PROFILE_RESET }); } }, [dispatch, userUpdateProfileSuccess]); const handleSubmit = (e) => { e.preventDefault(); dispatch(updateUserProfile(formData)); };
4. 检查后端JWT配置
确认settings.py中的Simple JWT配置是否合理,避免不必要的token失效:
from datetime import timedelta SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15), 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), 'ROTATE_REFRESH_TOKENS': True, 'BLACKLIST_AFTER_ROTATION': False, # 无需旧refresh token失效可设为False 'UPDATE_LAST_LOGIN': True }
内容的提问来源于stack exchange,提问作者saman barjawand
相关产品推荐
相关产品推荐

