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
相关产品推荐
相关产品推荐

