【问题标题】:Javascript annotations / decorators on normal functions普通函数上的 Javascript 注释/装饰器
【发布时间】:2022-06-19 00:37:37
【问题描述】:

我正在开发一个 Next.js 应用程序,并且我有一个按以下方式定义的 API:

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'GET') {
    fn1Get(req, res);
  } else if (req.method === 'POST') {
    fn1Post(req, res);
  } else {
    res.status(501).json({ operation: `${req.method}: not implemented` });
  }
}
async function fn1Get(
  req: NextApiRequest,
  res: NextApiResponse
): Promise<void> {
  const authenticated = await checkAuth(req, res);
  if (authenticated) {
      // Get Stuff
      res.status(200).json({status: 'all right!'});
  }
}
async function fn1Post(
  req: NextApiRequest,
  res: NextApiResponse
): Promise<void> {
  const authenticated = await checkAuth(req, res);
  if (authenticated) {
      // Post Stuff
      res.status(201).json({status: 'all right!'});
  }
}
const checkAuth = async (req: NextApiRequest, res: NextApiResponse) => {
  const tokenValid = await extnernalApiCall(getToken(req));
  if (!tokenValid) {
    res.status(403).json({ error: 'Authentication Failed' });
  }
  return tokenValid
};

我正在尝试找到一种更简单的设置来定义经过身份验证的方法,而不是在其中添加行 const authenticated = await checkAuth(req, res);

在 Java 或 Python 等其他语言中,我可以使用装饰器/注释/AOP,例如:

@checkAuth
async function fn1Get(
  req: NextApiRequest,
  res: NextApiResponse
):

我可以在 javascript 中做一些接近它的事情吗?也许通过包装函数,和/或使用绑定/调用/应用??

伪代码示例:

const checkAuth = async (fn) => {
  const req = arguments[1];
  const res = arguments[2];
  const tokenValid = await extnernalApiCall(getToken(req));
  if (!tokenValid) {
    res.status(403).json({ error: 'Authentication Failed' });
  }
  return fn(arguments);
}
async function fn1Get = checkAuth(_fn1Get(
  req: NextApiRequest,
  res: NextApiResponse
): Promise<void> {
  const authenticated = await checkAuth(req, res);
  if (authenticated) {
      // Get Stuff
      res.status(200).json({status: 'all right!'});
  }
})

如您所见,我要验证的所有函数都将接收相同的两个参数reqres(请求和响应),并且我的验证函数也需要这两个参数来获取要从中验证的令牌req 如果未通过身份验证,则在 res 中写入 403

我使用的技术是 Next.js 和 React 17、TypeScript、ECMA6

【问题讨论】:

    标签: javascript ecmascript-6 async-await next.js annotations


    【解决方案1】:

    是的,您可以使用包装函数来实现这一点(无论如何,这基本上就是装饰器)。该包装函数必须返回一个函数。类似于以下内容(您必须相应地调整类型):

    const checkAuth = (fn) => {
      return async (req: NextApiRequest,res: NextApiResponse): Promise<void> => {
        const tokenValid = await extnernalApiCall(getToken(req));
        if (!tokenValid) {
          res.status(403).json({ error: 'Authentication Failed' });
        } else {
          fn(req, res);
        }
      }
    }
    
    const fn1Get = checkAuth((
      req: NextApiRequest,
      res: NextApiResponse
    ): Promise<void> => {
      // Get Stuff
      res.status(200).json({status: 'all right!'});
    })
    

    话虽如此,我对 next.js 并不熟悉。可能有一种方法可以注册中间件处理程序,该处理程序会在每个请求上触发,而无需显式包装每个处理程序。

    【讨论】:

    • 该死!我真的很亲近!!非常感谢!!您在 fn1Get 中缺少一个箭头:: Promise&lt;void&gt; =&gt; { 请为其他阅读答案的人编辑它! =)
    【解决方案2】:

    我使用 next js 和 next-auth 进行身份验证。 我做了一个函数来检查请求是否有会话。如果没有会话,用户将被重定向到登录页面。如果用户有会话,它会将 props 传递给 getServerSideProps 函数。

    import { getSession } from "next-auth/react";
    
    /* gssp =  */
    export const requireAuth = (gssp) => {
      return async (ctx) => {
          const { req } = ctx;
          const session = await getSession({ req })
          if (!session) {
              return {
                  redirect: { permanent: false, destination: '/api/auth/signin' }
              };
          };
          const ctxWithSession = { ...ctx, session };
          return await gssp(ctxWithSession);
      };
    };
    

    然后,我在下一个 js 页面中将此函数称为 getServerSideProps 的高级函数:

    export const getServerSideProps = requireAuth(async _ctx => {
        const { session } = _ctx;
        return {
            props: {
              session: session,  
            },
        };
    });
    

    【讨论】:

      猜你喜欢
      • 2013-02-10
      • 2019-11-13
      • 2021-11-20
      • 2022-09-21
      • 2017-05-04
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多