Nextjs 高阶 API 函数:解析器不是函数

Nextjs higher order API function: resolver is not a function

我想为我的 NextJs API 路由编写一个包装器来检查请求中的 JWT,验证它然后执行原始 API 处理程序。

所以我已经像这样定义了我的包装函数

interface ApiError {
  message: string,
}

export async function withJwt<T>(
  handler: ((req: NextApiRequest, res: NextApiResponse<T>, user?: User)=>void|Promise<void>))
  : Promise<(req: NextApiRequest, res: NextApiResponse<T | ApiError>)=>Promise<void>> {  
  return async (req: NextApiRequest, res: NextApiResponse<T | ApiError>) => {
    const authHeader = req.headers.authorization;
    if(!authHeader || !authHeader.startsWith(JWT_PREFIX)){ 
      return res.status(401).json({
        message: `Provide the header 'Authorization: ${JWT_PREFIX}<token>'`,
      });
    }
    let user: User;
    try {
      user = await verify(authHeader.substring(JWT_PREFIX.length));
    } catch(err) {
      return res.status(401).json({message: (err as any).message as string});
    }

    try {
      return handler(req, res, user);
    } catch(err){
      return res.status(500).json({message: (err as any).message});
    }
  };
}

然后,我的API路线看起来像这样

// page/api/hello.ts

type Data = {
  name: string
}

const wrapped = withJwt((
  req: NextApiRequest,
  res: NextApiResponse<Data>
) => {
  res.status(200).json({ name: 'John Doe' })
});

export default wrapped;

然而,当我导航到 /api/hello 时,我收到以下错误输出:

Server Error

TypeError: resolver is not a function

Uncaught at Object.apiResolver (file:///root/projects/taskmanager-next/node_modules/next/dist/server/api-utils.js:101:15) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async DevServer.runApi (file:///root/projects/taskmanager-next/node_modules/next/dist/server/next-server.js:320:9) at async Object.fn (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:486:37) at async Router.execute (file:///root/projects/taskmanager-next/node_modules/next/dist/server/router.js:228:32) at async DevServer.run (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:598:29) at async DevServer.run (file:///root/projects/taskmanager-next/node_modules/next/dist/server/dev/next-dev-server.js:444:20) at async DevServer.handleRequest (file:///root/projects/taskmanager-next/node_modules/next/dist/server/base-server.js:305:20)

我在这里错过了什么?

好的,我明白了:

我的错误是将 withJwt 设为 async 函数。只有 returned 函数需要 async,因此 return 是一个 Promise。

所以以下是有效的:

export function withJwt<T>(
  handler: ((req: NextApiRequest, res: NextApiResponse<T>, user?: User)=>void|Promise<void>))
  : (req: NextApiRequest, res: NextApiResponse<T | ApiError>)=>Promise<void> {  
  return async (req: NextApiRequest, res: NextApiResponse<T | ApiError>) => {
    const authHeader = req.headers.authorization;
    if(!authHeader || !authHeader.startsWith(JWT_PREFIX)){ 
      return res.status(401).json({
        message: `Provide the header 'Authorization: ${JWT_PREFIX}<token>'`,
      });
    }
    let user: User;
    try {
      user = await verify(authHeader.substring(JWT_PREFIX.length));
    } catch(err) {
      return res.status(401).json({message: (err as any).message as string});
    }

    try {
      return handler(req, res, user);
    } catch(err){
      return res.status(500).json({message: (err as any).message});
    }
  };
}