正常功能的JavaScript注释 /装饰器

发布于 2025-01-24 11:55:50 字数 2288 浏览 3 评论 0原文

我正在开发一个spect.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 part auth persionatication =等待checkauth(等待checkauth( req,res); < / code>

在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!'});
  }
})

如您所见,我要身份验证的所有功能都将接收相同的两个参数req res> res (请求和响应)以及我的身份验证函数还需要两个参数才能使令牌从req进行身份验证,并在res res中编写403,如果未经认证,

我正在使用的技术是Next.js,反应17,打字稿,ecma6

I am developing a Next.js application, and I have an API defined in the following way:

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
};

I am trying to find an easier setup to define authenticated methods, instead of adding inside of them the line const authenticated = await checkAuth(req, res);

In other languages like Java or Python I could use decorators / annotations / AOP, something like:

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

Can I do something close to it in javascript? Maybe via wrapping functions, and/or using bind/call/apply??

Pseudo-code example:

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!'});
  }
})

As you can see, all the functions that I want to authenticate will receive the same two parameters req and res (request and response), and my authentication function also need both parameters to get the token to authenticate from the req and write a 403 in res if it is not authenticated

The technologies I'm using are Next.js with React 17, TypeScript, ECMA6

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

且行且努力 2025-01-31 11:55:50

是的,您可以通过包装器功能来实现此目标(无论如何,这基本上就是装饰器)。该包装器功能必须返回功能。类似以下内容(您必须相应地调整类型):

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并不熟悉。可能有一种注册中间软件处理程序的方法,可以在每个请求上发射,而无需明确包装每个处理程序。

Yes, you can achieve this with a wrapper function (that's basically what decorators are anyway). That wrapper function has to return a function. Something like the following (you'll have to adjust the types accordingly):

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!'});
})

Having said that, I'm not familiar with next.js. There might be a way to register middelware handlers that would fire on every request without you having to wrap every handler explicitly.

一指流沙 2025-01-31 11:55:50

我将下一个JS与Next-auth一起进行身份验证。
我做了一个函数,可以检查请求是否有会话。如果没有会话,则用户将重定向到页面中的符号。如果用户有会话,则将道具传递给 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,  
        },
    };
});

I use next js along with next-auth for authentication.
I made a function that checks if the request has a session. If no session, the user gets redirected to the sign in page. If the user has a session, it passes the props to getServerSideProps function.

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);
  };
};

Then, i call this function in my next js page as a higher function of getServerSideProps :

export const getServerSideProps = requireAuth(async _ctx => {
    const { session } = _ctx;
    return {
        props: {
          session: session,  
        },
    };
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文