Next-Auth:在没有 getServerSideProps 的情况下使会话在 _app.js 可用

Next-Auth: Make Session Available In _app.js Without getServerSideProps

使用 React.jsReact-Auth 时,调用 getServerSideProps 等服务器端函数将阻止您通过 next export 导出项目。这是我的pages/_app.js的内容,我从文档(https://next-auth.js.org/getting-started/client and also https://github.com/nextauthjs/next-auth/issues/1210#issuecomment-782630909)复制了结构:

export default function App({
  Component,
  pageProps: { session, ...pageProps },
}) {
  return (
    console.log(session), // -> undefined in server- and client-console
    <SessionProvider session={session}>
      {Component.auth ? (
        <Auth>
          <Component {...pageProps} />
        </Auth>
      ) : (
        <Component {...pageProps} />
      )}
    </SessionProvider>
  )
}

function Auth({ children }) {
  const { data: session, status, loading } = useSession({required: true})
  const isUser = !!session?.user 
  console.log(session)// -> undefined in server- but correct in client-console
  React.useEffect(() => {
      if (loading) return   // Do nothing while loading
      if (!isUser) signIn()
  }, [isUser, loading])

  if (isUser) {
    return children
  }

  // Session is being fetched, or no user.
  // If no user, useEffect() will redirect.
  return <div>Loading...</div>
}

这里的问题是 session 在服务器端总是 undefined。每次成功登录后,我都会在回调将我带到所需的受保护页面后重定向到 signIn 页面。但是,我认为 useEffect 只会在客户端 运行 - 因此我不确定为什么我会重定向到 signIn().

但是,请考虑以下文件 pages/index.js:

export default function Index() {
  const {data: session} = useSession();
  console.log(session); // -> will return actual session
  // session is always non-null inside this page, all the way down the React tree.
  return "Some super secret dashboard"
}

Index.auth = false // For testing, to avoid redirect to signIn

在这里我可以毫无问题地阅读会话(即使会话似乎一直在重新创建)。看来我必须找到一种方法将会话数据推送到 pageProps。否则每次(成功)登录后我都会被重定向到登录页面。

如果我将以下代码添加到 pages/index.js(在 page/_app.js 中不起作用),会话数据已正确添加到 pages/_app.js 中的 pageProps :

export async function getServerSideProps(ctx) {
  return {
    props: {
      session: await getSession(ctx)
    }
  }
}

session 添加到 pages/_app.js 中的 pageProps 而不使用像 getServerSideProps 这样的任何服务器端函数的最佳方法是什么?

useEffect-Hook 实际上有问题:

React.useEffect(() => {
    if (loading) return   // Do nothing while loading
    if (!isUser) signIn()
}, [isUser, loading])

loading 没有说实话。我这样修改了块:

React.useEffect(() => {
    if (status === 'loading') return   // Do nothing while loading
    if (!isUser) signIn()
}, [isUser, status])

登录现在按预期工作。