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

Next.js中如何访问_app.js渲染组件内的Cookie信息

实现方案

方案1:客户端校验(最简易,适合非httpOnly Cookie场景)

你已经在_app.js中配置了react-cookie的CookiesProvider,直接在Nav组件内调用钩子读取Cookie做判断即可,修改后的代码如下:

import Link from 'next/link';
import { useRouter } from 'next/router';
import axios from 'axios';
import { doOAuthWork } from '../lib/handleDiscordOAuth2';
import { useCookies } from 'react-cookie';
import { useEffect, useState } from 'react';

const Nav = () => {
  // 替换成你实际存储OAuth令牌的Cookie字段名
  const [cookies] = useCookies(['discord_oauth_token']);
  const [isTokenValid, setIsTokenValid] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // 先判断Cookie是否存在
    if (!cookies.discord_oauth_token) {
      setIsTokenValid(false);
      setLoading(false);
      return;
    }
    // 可选:发请求到后端校验令牌有效性,避免伪造Cookie
    const verifyToken = async () => {
      try {
        // 替换成你的校验接口地址
        await axios.get('/api/auth/verify', { withCredentials: true });
        setIsTokenValid(true);
      } catch (e) {
        setIsTokenValid(false);
      } finally {
        setLoading(false);
      }
    };
    verifyToken();
  }, [cookies.discord_oauth_token]);

  return (
    <div className="navbar z-10 top-0 fixed shadow-lg bg-neutral text-neutral-content inset-x-0 bg-opacity-80 backdrop-filter backdrop-blur-lg">
      <div className="px-2 mx-2 navbar-start">
        <span className="text-lg font-bold">
          Status+
        </span>
      </div>
      <div className="hidden px-2 mx-2 navbar-center lg:flex">
        <div className="flex items-stretch">
          <div className="btn btn-ghost btn-sm rounded-btn">
            <Link href="/">
              Home
            </Link>
          </div>
          <div className="btn btn-ghost btn-sm rounded-btn">
            <Link href="/">
              Status
            </Link>
          </div>
          <div className="btn btn-ghost btn-sm rounded-btn">
            <Link href="/">
              Dashboard
            </Link>
          </div>
        </div>
      </div>
      <div className="navbar-end">
        {/* 加载中可渲染占位符,校验通过则不显示登录模块 */}
        {!loading && !isTokenValid && doOAuthWork()}
      </div>
    </div>
  );
};
export default Nav;

方案2:服务端预取校验(兼容httpOnly Cookie,避免首屏闪烁)

如果你的令牌Cookie设置了httpOnly属性(安全性更高,推荐配置),客户端JS无法读取,可以用_app.js的getInitialProps在服务端拿到Cookie校验后传给组件,修改后的代码如下:

import 'tailwindcss/tailwind.css';
import Head from 'next/head';
import { CookiesProvider } from 'react-cookie';
import Nav from '../components/Nav';
import discordOAuth2 from '../lib/handleDiscordOAuth2';
import cookie from 'cookie';

function MyApp({ Component, pageProps, isAuthValid }) {
  return (
    <CookiesProvider>
      <>
        <Head>
          <title>Next and MDX Blog</title>
        </Head>
        <div className="container-fluid mx-auto w-full scrollhost" id="container4">
          {/* 将服务端校验结果传给Nav组件 */}
          <Nav isAuthValid={isAuthValid} />
          <main className="scrollhost" id="container2">
            <Component {...pageProps} />
          </main>
        </div>
      </>
    </CookiesProvider>
  );
}

MyApp.getInitialProps = async ({ ctx }) => {
  let isAuthValid = false;
  // 服务端读取请求头中的Cookie
  if (ctx.req?.headers.cookie) {
    const cookies = cookie.parse(ctx.req.headers.cookie);
    const token = cookies.discord_oauth_token;
    if (token) {
      // 此处可添加服务端调用OAuth接口校验令牌的逻辑
      isAuthValid = true;
    }
  }
  return { isAuthValid };
};

export default MyApp;

注意:getInitialProps会关闭Next.js的自动静态优化,如果你站点大部分是静态页面,优先使用方案1即可。

额外注意点

  • 生产环境建议OAuth令牌Cookie设置httpOnly、secure、sameSite属性,避免XSS攻击窃取
  • 令牌有效性校验优先走后端接口,不要只在客户端判断Cookie是否存在,避免伪造Cookie绕过校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:24:03