启用密钥时按钮触发On-demand Revalidate,前端请求.env令牌未识别
问题核心原因
Next.js 中,未添加 NEXT_PUBLIC_ 前缀的环境变量仅能在服务端代码中访问。你的 index.js 是客户端组件(包含交互逻辑,会在浏览器中运行),虽然服务端渲染时 console.log 能输出 MY_SECRET_TOKEN 的值,但当代码在浏览器中执行 fetch 请求时,process.env.MY_SECRET_TOKEN 是 undefined,导致请求 URL 中的 secret 参数无效,接口返回 401 状态码,所以你看不到响应。
另外,直接在客户端传递敏感的 secret 令牌存在严重安全风险,会将密钥暴露给所有访问页面的用户。
解决方案
方案一:通过中间服务端路由触发重新验证
创建一个无需客户端传递 secret 的中间 API 路由,在服务端内部完成重新验证逻辑:
- 创建
/api/trigger-revalidate文件:
export default async function handler(req, res) { try { // 服务端直接调用 revalidate,无需从客户端接收 secret await res.revalidate('/path-to-revalidate'); return res.json({ revalidated: true }); } catch (err) { return res.status(500).send('Error revalidating'); } }
- 修改
index.js中的revalidate函数:
function revalidate() { fetch('/api/trigger-revalidate') .then(res => res.json()) .then(data => console.log('重新验证成功:', data)) .catch(err => console.error('重新验证失败:', err)); }
方案二:添加用户权限验证(更安全)
如果需要限制只有特定用户能触发重新验证,可以在中间路由中加入身份校验(示例用 NextAuth 做身份验证):
// /api/trigger-revalidate import { getSession } from 'next-auth/react'; export default async function handler(req, res) { const session = await getSession({ req }); // 验证用户是否为管理员或有权限的用户 if (!session || !session.user.isAdmin) { return res.status(401).json({ message: '无权限执行此操作' }); } try { await res.revalidate('/path-to-revalidate'); return res.json({ revalidated: true }); } catch (err) { return res.status(500).send('Error revalidating'); } }
关键提醒
永远不要在客户端代码中直接使用或传递敏感的服务端环境变量,这会导致密钥泄露,引发安全问题。服务端环境变量应仅在服务端代码中访问和使用。
内容的提问来源于stack exchange,提问作者journalsup
相关产品推荐
相关产品推荐

