【问题标题】:How to use secret key for on-demand revalidation for ISR (Next.js) in the frontend without exposing it?如何在前端使用密钥对 ISR (Next.js) 进行按需重新验证而不暴露它?
【发布时间】:2022-07-06 17:25:12
【问题描述】:

根据the documentation,您应该使用 SECRET_TOKEN 来防止未经授权访问您的重新验证 API 路由,即

https://<your-site.com>/api/revalidate?secret=<token>

但是您应该如何从前端调用该路由并保密令牌?

例如,如果您有一个简单的 POST,然后想要触发重新验证,您必须通过 NEXT_PUBLIC 公开您的秘密令牌才能使用它:

function handleSubmit(payload) {
  axios.post(POST_URL, payload)
  .then(() => {
    axios.get(`/api/revalidate?secret=${process.env.NEXT_PUBLIC_SECRET_TOKEN}`)
  })
  .then(() => {
    // redirect to on-demand revalidated page
  })
}

我在这里缺少什么?如何在不暴露 SECRET_TOKEN 的情况下通过前端调用 API 路由?

【问题讨论】:

  • 重新验证路线只适合您。你不应该从你的字体端调用它。
  • @MattTimmermans 但我相信一个常见的用例是如果用户编辑页面并且您想立即向他们显示编辑的页面 - 您将不得不使用按需重新验证。根据我在下面的回答,Next.js 的按需重新验证视频实际上不使用 SECRET_KEY 所以我想我只是省略了它并希望没有用户滥用 API 路由?
  • 如果 lots 用户或 任何 用户可以执行更改页面的操作,则它不是静态的。如果我们谈论的是被特别授权编辑页面的用户,那么您可以使用密钥仅信任他们,或者使用您用来保护编辑的相同身份验证 + 授权来保护该路由功能。
  • @MattTimmermans - 我的意思是在我的特定用例中,假设我有可以制作 cmets 的用户。我想允许用户编辑评论并通过按需重新验证更新该特定评论。据我所知,在这种特定情况下没有办法保护重新验证路线?任何人都可以GEThttps://<your-site.com>/api/revalidate?slug=/comment/123 重新验证/comment/123 而不仅仅是原始评论者。
  • 那不是静态页面。使用 getServerSideProps 代替 getStaticProps,完全不用担心重新验证。

标签: next.js


【解决方案1】:

Next.js 视频演示实际上并未使用 SECRET_KEY。

https://www.youtube.com/watch?v=BGexHR1tuOA

所以我想我只需要省略它并希望没有人滥用重新验证 API?

【讨论】:

  • 您找到更好的解决方案了吗?我在这里面临同样的问题。我想到的唯一想法是增加一个由前端调用的 API 函数,作为回报,它使用密钥调用 API 路由(因为密钥现在在下一个服务器上可用)。
  • 不过话说回来,任何人都可以调用这个中间API函数,所以实际上是一样的。
  • @Kox - 不,很遗憾,我从未找到解决方案。目前看来不可能。
  • 是的,这似乎超出了 Next 的范围。但是,文档似乎是多余的。 nextjs.org/blog/…
【解决方案2】:

我认为您需要创建一个名为“.env”的文件。

在文件中,您将参数 .env 像这样:

NEXT_PUBLIC_SECRET_TOKEN=123password

你必须安装依赖dotenv:

npm i dotenv

然后你可以像这样在你的函数内部调用

function handleSubmit(payload) {
  axios.post(POST_URL, payload)
    .then(() => {
      axios.get(`/api/revalidate?secret=${process.env.NEXT_PUBLIC_SECRET_TOKEN}`)
    })
    .then(() => {
      // redirect to on-demand revalidated page
    })
}

【讨论】:

  • 哎呀,是的,你是对的。我忘了在我的 OP 中包含 process.env。但是我的问题集中在文档如何说要保持 SECRET_TOKEN 秘密,但如果我想在前端使用它,我必须通过 NEXT_PUBLIC_ 公开它。那么,如果我想在前端使用令牌,我应该如何保密呢?
【解决方案3】:

我一直在尝试按需 ISR 并偶然发现了一个类似的问题。我试图在客户端上受保护的路由(“/admin/...”)后面从我的管理仪表板执行 CRUD 操作后重新验证数据。

如果您设置了身份验证流程并且您正在使用 Next-Auth 的 JWT 策略,那么您可以访问 getToken() 方法,该方法会解密当前经过身份验证的用户的 JWT。

然后,您可以使用通过callbacks 传递的任何信息来验证请求,而不是依赖SECRET_TOKEN

import type { NextApiRequest, NextApiResponse } from "next";
import { getToken } from "next-auth/jwt";

const secret = process.env.NEXTAUTH_SECRET;

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const user = await getToken({ req, secret });
  if (!user || user.role !== "ADMIN") {
    return res.status(401).json({ message: "Revalidation not authorized"});
  }

  try {
    // unstable_revalidate is being used in Next 12.1
    await res.unstable_revalidate(req.query.url as string);
    return res.json({ revalidated: true });
  } catch (err) {
    return res.status(500).send("Error revalidating");
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 2020-07-13
    相关资源
    最近更新 更多