我们目前正在针对用户特定的流程,需要一些防护措施以防止用户访问某些页面。我们基于来自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.redirect
和res.end
的重定向实用程序)
export const checkForCart = ({ cart, checkout }, res) => {
const { rows = [] } = checkout || {}
if (!cart || !rows.length) {
return handleRedirect('CART', res)
}
}
这看起来不错,因为我们只能使用checkForCart()
,而不必在每个页面上重复此代码。它有一个问题,那就是return
实用程序的checkForCart
仅返回函数,而不返回页面。因此,由于重定向需要一些时间,因此执行checkForCart()
下的代码。因此,如果我在console.log
下执行checkForCart(viewer, res)
,它将记录。
是否存在一种从util停止执行的巧妙方法,还是在Next.js中解决这种情况的一种便捷方法?实施“警卫”之类的最佳方法是什么?
答案 0 :(得分:1)
getInitialProps
是async
函数,这意味着您可以利用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)
}
}