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

Next.js Strapi Apollo GraphQL认证跳转与状态更新失效问题

Next.js + Strapi + GraphQL 认证功能问题修复

核心问题定位

  • 登录页跳转失效:页面内监听用户状态触发跳转的useEffect依赖数组为空,仅在组件首次挂载时执行一次。登录请求返回更新Context中的用户状态后,钩子不会重新触发,因此router.push不会执行。
  • 页面刷新/业务页状态检测失效:全局用户Context未做持久化同步,页面刷新后Context状态重置为初始值,不会自动读取Cookie中存储的JWT令牌恢复登录态;同时部分useEffect依赖声明不全,存在闭包陷阱导致拿到旧状态值。
  • 隐性逻辑冲突:登出逻辑先执行路由跳转再清空用户状态,跳转过程中路由守卫检测到未清空的用户状态会出现逻辑判断错误;本地图片引入、JSX属性写法存在不规范问题会触发控制台警告。

分步修复方案

1. 修复登录页跳转逻辑

修改登录页监听用户状态的useEffect,补全依赖项,同时添加路由参数防止登录后回退到登录页:

// 原代码依赖为[],修改为[user, router]
useEffect(() => {
  if (user !== "" && user !== undefined) {
    router.push("/account", undefined, { replace: true });
  }
}, [user, router]);

更稳妥的方式是直接在登录Mutation的完成回调里处理状态更新和跳转,避免依赖状态同步的延迟:

const [loginUser, { loading, error, data }] = useMutation(LOGIN_USER, {
  onCompleted: (loginData) => {
    const userInfo = {
      token: loginData.login.jwt,
      username: loginData.login.user.username,
      id: loginData.login.user.id,
      email: loginData.login.user.email,
    }
    // 更新全局状态
    dispatchUser(setUserAction(userInfo, SIGN_IN));
    // 持久化存储:JWT存Cookie,用户信息存localStorage
    document.cookie = `jwt=${loginData.login.jwt}; path=/; max-age=86400; SameSite=Lax`;
    localStorage.setItem('userInfo', JSON.stringify(userInfo));
    // 跳转至账号页
    router.push("/account", undefined, { replace: true });
  }
});
// 删除原代码中监听data变化的useEffect,避免重复执行逻辑

2. 修复全局Context持久化逻辑

在UserWrapper上下文组件中添加初始化逻辑,页面加载时自动读取本地存储恢复登录态:

// 在UserWrapper组件内部添加初始化钩子
useEffect(() => {
  // 封装Cookie读取方法
  const getCookie = (name) => {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
    return null;
  };
  const token = getCookie('jwt');
  const savedUser = localStorage.getItem('userInfo');
  // Cookie存在有效令牌时恢复全局状态
  if (token && savedUser) {
    dispatchUser(setUserAction(JSON.parse(savedUser), SIGN_IN));
  }
}, []);

同时在Context的reducer中补充状态清理逻辑:触发SIGN_OUT动作时,同步清除Cookie和localStorage中存储的登录信息。

3. 修复业务页路由守卫与登出逻辑

修改账号页的状态检测useEffect,补全依赖项避免闭包问题;调整登出逻辑执行顺序,先清状态再跳转:

// 补全useEffect依赖数组
useEffect(() => {
  if (user) {
    getUserOrders({
      variables: {
        filters: {
          user: { id: { eq: user.id } },
          status: { ne: "rejected" },
        },
      },
    });
  } else {
    router.push("/account/login", undefined, { replace: true });
  }
}, [user, router, getUserOrders]);

// 调整登出逻辑顺序
const handleLogout = () => {
  // 先清空全局状态、本地存储
  dispatchUser(setUserAction(null, SIGN_OUT));
  document.cookie = "jwt=; path=/; max-age=0";
  localStorage.removeItem('userInfo');
  // 最后跳转至登录页
  router.push("/account/login", undefined, { replace: true });
};

4. 其他不规范问题修复

  • 本地静态图片不要用require引入,直接在文件顶部导入:import logo from "../../public/Img/logo.png",Image组件src属性直接传入导入的logo变量即可
  • JSX中label的for属性替换为htmlFor,避免和JS保留字冲突触发React警告
  • 密码输入框的type属性从text改为password,防止输入内容明文显示
  • 补全代码中缺失的useLazyQuery、图标组件、常量等导入,避免编译报错

验证标准

修复后按以下流程验证功能:

  • 输入正确账号密码提交登录,成功后自动跳转至账号个人页,点击浏览器后退按钮不会回到登录页
  • 登录状态下刷新任意业务页面,不会自动跳转到登录页,用户信息、订单数据正常加载
  • 点击登出按钮后,登录状态被清空,自动跳转至登录页,此时直接访问/account路由会被拦截跳回登录页
  • 手动在浏览器中写入有效JWT Cookie后访问站点,会自动识别登录态进入对应页面,无需重复登录

内容的提问来源于stack exchange,提问作者Dilshod Sh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 10:45:29