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

Next.js App Router如何在服务端调用/api/auth/me接口?

解决方案:Next.js App Router服务端获取用户信息并适配谷歌广告

核心问题说明

服务端无法直接访问localStorage,必须把登录Token转移到Cookie中,这样服务端才能从请求头里拿到Token完成接口调用。

步骤1:调整Token存储逻辑

登录成功后,除了把Token存入localStorage,还要存入Cookie(服务端可读取):

// 登录成功后的前端处理逻辑
const loginSuccess = (token) => {
  // 存入localStorage(供前端后续使用)
  localStorage.setItem('token', token);
  // 存入Cookie(供服务端读取),可根据需求调整过期时间、安全属性
  document.cookie = `token=${token}; path=/; max-age=86400; SameSite=Lax`;
};

步骤2:在RootLayout(服务端组件)中获取用户信息

App Router中layout.tsx默认是服务端组件,可直接获取请求Cookie并调用接口,修改后的代码如下:

import "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import Sidebar from "../components/Sidebar";
import { cookies } from 'next/headers';

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

// 服务端函数:获取用户信息
async function getUserInfo() {
  const cookieStore = cookies();
  const token = cookieStore.get('token')?.value;
  
  if (!token) {
    return null;
  }
  
  try {
    // 服务端调用接口无需跨域,直接用内部地址或完整域名
    const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/auth/me`, {
      headers: {
        Authorization: `Bearer ${token}`
      }
    });
    
    if (!res.ok) throw new Error('用户信息请求失败');
    return await res.json();
  } catch (error) {
    console.error('获取用户信息出错:', error);
    return null;
  }
}

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const user = await getUserInfo();
  
  return (
    <html lang="da" className="h-full bg-gray-100">
      <body className="h-full bg-gray-100">
        <Sidebar user={user} />
        {children}
      </body>
    </html>
  );
}

步骤3:适配谷歌广告服务端渲染

如果谷歌广告需要根据用户状态调整展示内容,可按以下方式处理:

  • 将用户信息通过props传递给广告组件;
  • 广告组件若为客户端组件,需声明'use client',再根据user状态加载对应广告单元;
  • 推荐用Next.js的<Script>组件加载谷歌广告脚本,确保加载时机正确:
// 客户端广告组件示例
'use client';

import Script from 'next/script';

export default function GoogleAd({ user }) {
  // 根据用户状态切换广告单元ID
  const adSlotId = user ? '已登录用户广告单元ID' : '未登录用户广告单元ID';
  
  return (
    <>
      <Script
        async
        src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXXX"
        crossOrigin="anonymous"
      />
      <ins
        className="adsbygoogle"
        style={{ display: 'block' }}
        data-ad-client="ca-pub-XXXXXXXXXXXXXX"
        data-ad-slot={adSlotId}
        data-ad-format="auto"
        data-full-width-responsive="true"
      />
      <Script id="google-ad-init">
        {`(adsbygoogle = window.adsbygoogle || []).push({});`}
      </Script>
    </>
  );
}

注意事项

  • 生产环境建议给Cookie添加secure: true属性,仅通过HTTPS传输,提升安全性;
  • 接口调用失败时要优雅降级,返回null确保页面正常渲染;
  • 若/api/auth/me是自身项目的API路由,建议直接调用业务逻辑函数而非HTTP请求,提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:47:36