You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

更新用户资料后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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:36:13