如何在Next.js中安全获取httpOnly Cookie的Token用于Apollo Client?
核心思路
利用Next.js服务端渲染特性,在_app.js的getServerSideProps中读取HttpOnly Cookie里的Token,传递给Apollo Client用于服务端请求;同时配置Apollo Client允许跨域携带Cookie,让客户端请求自动传递Cookie,由API服务器直接从Cookie提取Token(若API支持该方式)。若API必须要求Authorization头,服务端请求直接添加头信息,客户端请求则依赖API兼容Cookie验证逻辑。
修改后的_app.js代码
import { ApolloProvider, ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client'; import { setContext } from '@apollo/client/link/context'; import Layout from '../components/Layout'; // 请根据实际路径调整 export function MyApp({ Component, pageProps, initialToken }) { const httpLink = createHttpLink({ uri: 'http://localhost:4000/graphql', withCredentials: true, // 关键:允许跨域请求自动携带Cookie }); const authLink = setContext((_, { headers }) => { // 服务端渲染时使用从Cookie读取的initialToken,客户端渲染依赖Cookie自动传递 const token = initialToken; return { headers: { ...headers, ...(token && { Authorization: `Bearer ${token}` }), }, }; }); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), ssrMode: typeof window === 'undefined', // 适配服务端/客户端渲染模式 }); return ( <ApolloProvider client={client}> <Layout> <Component {...pageProps} /> </Layout> </ApolloProvider> ); } // 服务端读取HttpOnly Cookie中的Token,传递给页面组件 export async function getServerSideProps(context) { const { req } = context; const initialToken = req.cookies.token || ''; return { props: { initialToken, }, }; } export default MyApp;
关键配置说明
- 服务端Token获取:通过
getServerSideProps读取req.cookies.token,将Token作为initialToken传递给MyApp,服务端渲染时Apollo Client会用这个Token设置Authorization头。 - 跨域Cookie携带:
httpLink设置withCredentials: true,确保客户端请求自动携带Cookie到API服务器,需API服务器配合配置:- 开启
Access-Control-Allow-Credentials: true - 指定
Access-Control-Allow-Origin: http://localhost:3000(禁止使用*)
- 开启
- 环境适配:
ssrMode根据运行环境自动切换,让Apollo Client在服务端和客户端采用最优渲染逻辑。
安全说明
- 保持Token存储在HttpOnly Cookie中,彻底避免XSS攻击窃取Token的风险。
- 服务端读取Token的逻辑完全隔离于客户端JS,符合安全规范。
- 跨域配置严格指定Origin,同时建议API服务器开启CSRF防护(如验证Referer头、使用CSRF Token),降低跨站请求伪造风险。
内容的提问来源于stack exchange,提问作者débutant
相关产品推荐
相关产品推荐

