我们目前正在针对用户特定的流程,需要一些防护措施来防止用户访问某些页面。我们基于来自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()而不是在每个页面上都重复此代码。它有一个问题,那就是return实用程序的checkForCart仅返回该函数,而不返回该页面。因此,由于重定向需要花费一些时间,因此checkForCart() get下面的代码将被执行。因此,如果我在console.log以下执行checkForCart(viewer, res),它将记录。

是否有一种整洁的方法来停止从util执行,还是在Next.js中有一种整洁的方法来修复这种情况?实施“警卫”之类的最佳方法是什么?

最佳答案

getInitialPropsasync函数,这意味着您可以利用await语法。将checkForCart转换为一个返回诺言并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/

10-11 17:42