如何在NextJS API路由中使用with-iron-session获取session?
问题根因
getServerSideProps 运行在Next.js服务端Node.js环境中,你在其中发起的fetch请求是服务端侧发起的独立HTTP请求,和用户浏览器端的请求完全隔离:
- 服务端fetch不会自动携带用户请求上传的session cookie,
credentials: 'include'配置仅对浏览器端fetch生效,对Node环境无任何作用 - 服务端fetch使用相对路径
/watch无法正常解析,需要写完整的请求地址
解决方案
方案1(推荐):抽离公共逻辑,避免额外HTTP请求
直接把API路由中的业务逻辑抽成公共复用函数,在getServerSideProps中直接调用即可,无需额外发起fetch请求:
- 抽离公共逻辑,比如新建
lib/watchLogic.js:
export const getWatchContent = (user) => { // 原API路由中的业务逻辑写在这里 if(user){ return "Good" } throw new Error("403") }
- 调整API路由直接调用该函数:
import withSession from './your-with-session-path' import { getWatchContent } from 'lib/watchLogic' export default withSession((req, res) => { const user = req.session.get("user"); try { const data = getWatchContent(user) res.send(data) } catch(e) { res.status(403).end() } }
- 调整getServerSideProps直接调用该函数,删除fetch逻辑:
export const getServerSideProps = withSession(async ({ req, res }) => { const user = req.session.get("user"); if (!user) { return { redirect: { permanent: false, destination: "/" }, props: {} }; } // 直接调用公共逻辑获取数据 const watch = getWatchContent(user) return{ props: { user, watch } } })
方案2:手动携带cookie发起服务端fetch
如果你必须调用API路由,需要手动补全请求地址和cookie头:
export const getServerSideProps = withSession(async ({ req, res }) => { const user = req.session.get("user"); if (!user) { return { redirect: { permanent: false, destination: "/" }, props: {} }; } // 补全完整请求地址 + 手动携带用户cookie const baseUrl = process.env.NODE_ENV === 'production' ? '你的生产域名' : 'http://localhost:3000' const watchRes = await fetch(`${baseUrl}/api/watch`,{ headers: { Cookie: req.headers.cookie || '' } }); const watch = await watchRes.json(); return{ props: { user, watch } } })
内容的提问来源于stack exchange,提问作者xv47
相关产品推荐
相关产品推荐

