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

如何在Next.js应用中使用React Context API实现身份验证?

Next.js 结合后端 Passport 身份验证的前端实现方案

核心需求梳理

  • 基于 Next.js 开发 React 应用
  • 后端采用 Node.js + Passport.js + passport-local-mongoose + express.session 实现身份验证
  • 前端使用 Context API 存储用户登录状态数据

现有 AuthContext 代码优化与适配建议

你当前的 AuthProvider 代码已经具备基础的用户状态校验逻辑,但针对 Next.js 环境需要做一些适配和完善:

1. 环境变量适配 Next.js

Next.js 中前端可访问的环境变量需以 NEXT_PUBLIC_ 开头,需修改环境变量名:

// 原代码
const url = process.env.REACT_APP_SERVER;
// 修改为
const url = process.env.NEXT_PUBLIC_SERVER;

2. 完善错误处理逻辑

原代码 catch 块为空,建议添加错误提示,方便调试和用户感知:

.catch((err) => {
  message.error('用户状态校验失败,请刷新页面重试');
  console.error('Auth check error:', err);
})

3. 添加登录/登出等核心操作方法

在 AuthProvider 中封装与后端交互的身份操作方法,方便组件直接调用:

// 登录方法
const login = useCallback(async (credentials) => {
  try {
    const res = await axios.post(`${url}/v1/users/login`, credentials, { withCredentials: true });
    setUser(res.data);
    message.success('登录成功');
    return true;
  } catch (err) {
    message.error(err.response?.data?.message || '登录失败');
    return false;
  }
}, []);

// 登出方法
const logout = useCallback(async () => {
  try {
    await axios.post(`${url}/v1/users/logout`, {}, { withCredentials: true });
    setUser(null);
    message.success('已退出登录');
  } catch (err) {
    message.error('登出失败');
    console.error('Logout error:', err);
  }
}, []);

// 在 Provider 的 value 中暴露这些方法
value={{ user, setUser, login, logout }}

4. Next.js 路由适配

若使用 Next.js App Router,需在根布局 layout.js 中引入 AuthProvider,确保全局状态生效:

// app/layout.js
import { AuthProvider } from '@/contexts/AuthContext';

export default function RootLayout({ children }) {
  return (
    <html lang="zh-CN">
      <body>
        <AuthProvider>{children}</AuthProvider>
      </body>
    </html>
  );
}

5. 优化加载状态处理

避免页面切换时重复显示加载动画,可结合 Next.js 的 useRouter 调整 useEffect 依赖项,或在页面级别单独处理加载状态。

完整优化后的 AuthProvider 代码

import { createContext, useCallback, useEffect, useState } from 'react';
import { Spin, message } from 'antd';
import axios from 'axios';

const url = process.env.NEXT_PUBLIC_SERVER;
export const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  // 初始化校验用户状态
  useEffect(() => {
    setLoading(true);
    const getUser = async () => {
      const endPoint = `${url}/v1/users/auth`;
      await axios({
        method: 'GET',
        url: endPoint,
        withCredentials: true,
      })
        .then((res) => {
          const { data } = res;
          setUser(data);
        })
        .catch((err) => {
          message.error('用户状态校验失败,请刷新页面重试');
          console.error('Auth check error:', err);
        })
        .finally(() => {
          setLoading(false);
        });
    };
    getUser();
  }, []);

  // 登录方法
  const login = useCallback(async (credentials) => {
    try {
      const res = await axios.post(`${url}/v1/users/login`, credentials, { withCredentials: true });
      setUser(res.data);
      message.success('登录成功');
      return true;
    } catch (err) {
      message.error(err.response?.data?.message || '登录失败');
      return false;
    }
  }, []);

  // 登出方法
  const logout = useCallback(async () => {
    try {
      await axios.post(`${url}/v1/users/logout`, {}, { withCredentials: true });
      setUser(null);
      message.success('已退出登录');
    } catch (err) {
      message.error('登出失败');
      console.error('Logout error:', err);
    }
  }, []);

  return (
    <AuthContext.Provider value={{ user, setUser, login, logout }}>
      {loading ? (
        <div className='tmtube-global flexCenter'>
          <Spin size='large' />
        </div>
      ) : (
        children
      )}
    </AuthContext.Provider>
  );
};

后端接口配合注意事项

  • 确保后端配置正确的跨域规则,允许前端域名携带 Cookie
  • express.session 配置中需设置正确的 cookie.domain 和 sameSite 属性,适配前端域名
  • /v1/users/auth 接口需根据 session 返回当前登录用户信息,未登录则返回 401 或 null

内容的提问来源于stack exchange,提问作者Jorakuly Atamuradow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:01:06