NextJS 始终如一地访问每个页面的请求对象

Tho*_*mas 5 express next.js

我使用express+ passport+nextjs设置,将使用ID连接进行认证的应用程序。用户数据存储在请求对象上,使用express-sessionreq.user像往常一样为我提供每个请求。

现在我想将用户信息传递给前端,以便我可以将它用于某些事情,但似乎没有任何一致的方法可以对所有请求执行此操作。我可以getServerSideProps用于单个页面,但不能用于通过_document或 的每个页面_app。我该如何设置?

这是我的当前 _document.tsx

import Document, {
  Head,
  Main,
  NextScript,
  DocumentContext,
} from "next/document"

export default class Doc extends Document {
  public static async getInitialProps(ctx: DocumentContext) {
    const req: any = ctx.req
    console.log("req/user", `${!!req}/${!!(req && req.user)}`)
    const initialProps = await Document.getInitialProps(ctx)
    return {
      ...initialProps,
      user: req?.user || "no user",
    }
  }

  public render() {
    return (
      <html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

它似乎只在第一个请求期间返回一个请求对象,而不是页面的任何后续刷新。

我创建了一个在这里重现这个问题的小仓库:https : //github.com/rudfoss/next-server-custom-req

没有办法以简单的方式对所有页面执行此操作,这似乎很荒谬。

编辑:供参考,这是我的server.js. 它是 repo 中唯一的其他相关文件

const express = require("express")
const next = require("next")

const dev = process.env.NODE_ENV !== "production"

const start = async () => {
  console.log("booting...")
  const server = express()
  const app = next({ dev, dir: __dirname })
  const handle = app.getRequestHandler()
  await app.prepare()

  server.use((req, res, next) => {
    req.user = {
      authenticated: false,
      name: "John Doe",
    }
    next()
  })

  server.get("*", handle)

  server.listen(3000, (err) => {
    if (err) {
      console.error(err)
      process.exit(1)
    }

    console.log("ready")
  })
}

start().catch((error) => {
  console.error(error)
  process.exit(1)
})
Run Code Online (Sandbox Code Playgroud)

Kar*_*rky 10

建议通过函数组件来执行此操作,如Next.js 自定义应用程序文档中所示:

// /pages/_app.tsx
import App, { AppProps, AppContext } from 'next/app'

export default function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

MyApp.getInitialProps = async (appContext: AppContext) => {
  // calls page's `getInitialProps` and fills `appProps.pageProps`
  const appProps = await App.getInitialProps(appContext)
  const req = appContext.ctx.req

  return {
    pageProps: {
      ...appProps.pageProps,
      user: req?.user,
    },
  }
}
Run Code Online (Sandbox Code Playgroud)

正如您的回答所示,这将在每个请求上运行,因此自动静态优化不会处于活动状态。

尝试在以下 CodeSandbox 上进行更改(不使用 )pagePropsMyApp.getInitialProps演示:req.user

https://codesandbox.io/s/competent-thompson-l9r1u?file=/pages/_app.js