Next.js应用中fetch请求的Token是否对客户端用户可见
Next.js 内Fetch请求携带Token的安全性说明
核心结论:Token会不会泄露完全取决于你把这段fetch代码写在什么位置
- 如果代码写在服务端执行的场景(服务端组件、服务端动作Server Action、API路由、getServerSideProps/getStaticProps等服务端生命周期):
Token完全不会泄露给客户端,因为这段fetch请求是Next.js服务端发起的,整个请求过程都在服务端完成,客户端只能拿到你最终返回的渲染结果或者接口返回数据,看不到你服务端请求里带的Authorization头。 - 如果代码写在客户端执行的场景(
'use client'标记的客户端组件、useEffect等客户端生命周期内、普通前端事件回调里):
Token100%会泄露,用户只要打开浏览器开发者工具的网络面板,就能直接看到这个请求的完整请求头,拿到你的Bearer Token,拿来做任何你账号权限范围内的操作,风险极高。
符合最佳实践的实现方案
你要对接GitHub API的话,绝对不要把带Token的请求逻辑放到客户端去写,推荐两种安全的实现方式:
- 用服务端组件直接发起请求:所有数据请求在服务端完成,渲染完页面直接返回给客户端,全程Token不会暴露
- 封装成Next.js的API路由:如果你需要客户端触发请求(比如用户点击按钮加载数据),你可以写一个
app/api/github/route.ts的接口,在这个接口的服务端逻辑里发起带Token的GitHub请求,客户端只需要调用你自己的这个接口就行,不需要知道Token是什么。
你的参考代码调整示例
如果是写在服务端组件里,只要确保文件没有加'use client'标记,直接用你原来的代码就行,完全安全:
// 这里的TOKEN可以存在.env文件里,通过process.env.GITHUB_TOKEN读取,Next.js服务端可以直接拿到,客户端默认访问不到.env里的变量 const TOKEN = process.env.GITHUB_TOKEN!; async function getRepoData() { const res = await fetch(`https://api.github.com/graphql`, { method: 'POST', headers: { "Content-Type": 'application/json', 'Authorization': 'Bearer ' + TOKEN, }, body: JSON.stringify({ query: ` { search(query: "is:public", type: REPOSITORY, first: 10) { repositoryCount pageInfo { endCursor startCursor } edges { node { ... on Repository { name } } } } } ` }) }) return res.json() } // 服务端组件直接异步调用 export default async function RepoPage() { const data = await getRepoData(); return <div>{/* 渲染你的数据 */}</div> }
注意:绝对不要给.env里的Token变量加
NEXT_PUBLIC_前缀,加了的话这个变量会被打包到客户端代码里,也会导致泄露。
内容的提问来源于stack exchange,提问作者grom1717
相关产品推荐
相关产品推荐

