javascript - 使用 getInitialProps 保护路由 - Next.js

标签 javascript graphql next.js

我们目前正在研究特定于用户的流程,这需要一些保护措施来防止用户访问某些页面。我们根据来 self 们的 GraphQL API 的数据执行此操作,据我们所知,我们应该在 getInitialProps 中实现这些守卫。

我们想为此使用一些实用函数,而不是在每个页面上重写所有逻辑。看这里的例子:

我们 getInitialProps 的片段

Email.getInitialProps = async ({ req, res, apolloClient }) => {
  const deviceInfo = getDeviceInfo(req)

  try {
    const {
      data: { viewer },
    } = await apolloClient.query({
      query: GET_CHECKOUT,
      fetchPolicy: 'network-only',
    })

    checkForCart(viewer, res)
    checkForProcessingPayment(viewer, res)

    return {
      namespacesRequired: ['buy-common', 'common', 'buy-email'],
      deviceInfo,
    }
  } catch (error) {
    const { href, as } = getLinkProps('CART')
    return redirect({ href, as }, res)
  }
}

实用函数(handleRedirect 只是一个重定向实用程序,它在后台执行 res.redirectres.end)

export const checkForCart = ({ cart, checkout }, res) => {
  const { rows = [] } = checkout || {}

  if (!cart || !rows.length) {
    return handleRedirect('CART', res)
  }
}

这看起来不错,因为我们可以使用 checkForCart() 而不是为每个页面重复此代码。它有一个问题,那就是checkForCart util 的return 只返回函数,而不返回页面。因此,由于重定向需要一些时间,因此 checkForCart() 下面的代码得到执行。因此,如果我在 checkForCart(viewer, res) 下面执行 console.log,它将记录。

是否有一种巧妙的方法来停止从 util 执行,或者 Next.js 中是否有一种巧妙的方法来修复这种情况?实现类似“守卫”的最佳方式是什么?

最佳答案

getInitialProps 是一个 async 函数,这意味着您可以利用 await 语法。将 checkForCart 转换为一个返回 promise 和 await 的函数,然后处理结果。例如:

export const checkForCart = ({ cart, checkout }, res) => {
  const { rows = [] } = checkout || {}
  return new Promise((resolve, reject) => {
    if (!cart || !rows.length) {
      reject()
    }
    resolve()
  })
}

Email.getInitialProps = async ({ req, res, apolloClient }) => {
  const deviceInfo = getDeviceInfo(req)

  try {
    const {
      data: { viewer },
    } = await apolloClient.query({
      query: GET_CHECKOUT,
      fetchPolicy: 'network-only',
    })

    // If this rejects/fails because !cart || !rows.length
    // execution will jump to the catch block
    await checkForCart(viewer, res)

    // This won't run until checkForCart finishes and resolves
    checkForProcessingPayment(viewer, res)

    return {
      namespacesRequired: ['buy-common', 'common', 'buy-email'],
      deviceInfo,
    }
  } catch (error) {
    const { href, as } = getLinkProps('CART')
    return redirect({ href, as }, res)
  }
}

关于javascript - 使用 getInitialProps 保护路由 - Next.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58270738/

相关文章:

flutter - 如何从 GraphQL 生成 Dart - graphql 到 dart 生成器

javascript - 我可以将 HTML 选择与动态数组关联吗?

javascript - 数字类型 + 数字类型 = NaN?

typescript - DefinitelyTyped 用于 graphql

postgresql - 相关数据未从 Apollo 返回给客户端?

typescript - "npx prisma db seed"命令出现错误 : Command failed with exit code 1: ts-node --compiler-options { "module": "CommonJS"} prisma/seed. ts

javascript - 使用 Medium Story API 在 Next.js 中上游图像响应失败

javascript - Tailwindcss 不适用于 next.js;配置有什么问题?

javascript - 三.js制作静态立方体

javascript - 旧浏览器中的高效元素定位