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

Next.js SSR模式下获取当前用户数据的实现困惑与求助

问题:Next.js SSR模式下如何获取用户ID以获取Firestore Token?

我在使用Next.js的SSR(服务端渲染)模式获取用户数据时遇到了困惑。此前我一直采用React的Context API管理用户状态,该方案在常规场景下运行正常,但当需要通过SSR从API获取数据时出现了问题。我希望获取当前用户ID,以便从Firestore中获取对应的token。

以下是我当前的相关代码实现:

Auth.js 文件代码

export const AuthContext = createContext();
export function AuthProvider({ children }) {
  const [currentUser, setCurrentUser] = useState(null);
  useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      setCurrentUser(user);
    });
  }, []);
  return (
    <AuthContext.Provider value={{ currentUser }}>
      {children}
    </AuthContext.Provider>
  );
}

SSR相关代码

export async function getStaticProps() {
  const api = { auth: "token", };
  //fetch api
  return { props: { data, }, };
}

解答

咱先揪出核心问题:你现在用的getStaticProps其实是**静态生成(SSG)**的方法,它在项目构建阶段就跑完了,根本拿不到当前用户的动态信息——这就是你为啥在SSR场景下拿不到用户ID的关键原因之一。

接下来一步步解决问题:

1. 换用getServerSideProps替代getStaticProps

getServerSideProps是真正的SSR入口,它会在每次用户请求时都在服务端运行,能拿到请求上下文(包括cookie、请求头这些关键信息),这才是获取用户动态数据的正确姿势。

2. 把用户认证信息存在Cookie里

你的AuthContext是纯客户端逻辑(依赖useEffect和Firebase的onAuthStateChanged),服务端根本访问不到这个状态。所以得把用户ID(或者更安全的ID Token)存在Cookie里,让服务端能读得到。

修改你的AuthProvider,加一段存Cookie的逻辑:

import Cookies from 'js-cookie'; // 可以用这个库简化Cookie操作,也可以用原生document.cookie

export const AuthContext = createContext();
export function AuthProvider({ children, initialUser }) {
  const [currentUser, setCurrentUser] = useState(initialUser);

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      setCurrentUser(user);
      if (user) {
        // 把用户ID存入Cookie,设置1天有效期,路径覆盖全站
        Cookies.set('userId', user.uid, { expires: 1, path: '/' });
        // 要是追求更安全,也可以存Firebase的ID Token,后面服务端验证
        // user.getIdToken().then(token => Cookies.set('idToken', token, { expires: 1, path: '/' }))
      } else {
        // 用户登出时清除Cookie
        Cookies.remove('userId', { path: '/' });
      }
    });

    return unsubscribe;
  }, []);

  return (
    <AuthContext.Provider value={{ currentUser }}>
      {children}
    </AuthContext.Provider>
  );
}

3. 在服务端读取Cookie并获取Firestore Token

现在getServerSideProps里就能从请求上下文里拿到Cookie,进而获取用户ID,再去Firestore拿对应的token:

// 假设你已经初始化了Firebase Admin SDK
import admin from 'firebase-admin';

export async function getServerSideProps(context) {
  // 从请求头里解析Cookie
  const { cookie } = context.req.headers;
  let userId = null;

  if (cookie) {
    // 把Cookie字符串转成键值对
    const cookieMap = cookie.split(';').reduce((acc, item) => {
      const [key, value] = item.trim().split('=');
      acc[key] = value;
      return acc;
    }, {});
    userId = cookieMap.userId;
  }

  let token = null;
  if (userId) {
    // 去Firestore查询对应用户的token
    const userDoc = await admin.firestore().collection('users').doc(userId).get();
    if (userDoc.exists) {
      token = userDoc.data().token;
    }
  }

  return {
    props: {
      token,
      initialUser: userId ? { uid: userId } : null
    }
  };
}

4. 把服务端数据传给组件和Context

页面组件拿到getServerSideProps返回的props后,不仅可以直接用token,还能把initialUser传给AuthProvider,避免客户端初始化时的状态空白:

export default function UserPage({ token, initialUser }) {
  return (
    <AuthProvider initialUser={initialUser}>
      <div>
        {token ? `当前用户Token:${token}` : '请先登录'}
      </div>
    </AuthProvider>
  );
}

额外提醒

  • 安全方面:如果存的是敏感信息,生产环境下要给Cookie加上HttpOnly和Secure属性,防止XSS攻击。要是用Firebase的ID Token,服务端一定要调用admin.auth().verifyIdToken(idToken)验证合法性,避免伪造。
  • 如果你只是需要用户的基本信息,也可以直接在服务端用ID Token解析出用户ID,不用存用户ID到Cookie,这样更安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:42:40