使用NodeJS/Express中的API Gateway进行微服务API身份验证

5
我正在使用Node JS和Express创建微服务架构。我知道微服务的主要特点之一是面向服务的架构,团队可以独立设计、开发和发布他们的应用程序。因此,在我的设计中,每个微服务都提供它们的API,并通过API相互通信,这样每个微服务就是独立的,并且有它自己的生命周期,等待请求。
由于我对微服务之间的身份验证和通信存在几个疑问,所以才写下这个问题。为了进行身份验证,我进行了JWT测试来验证微服务的API,并且一切都运行良好。以下是一个用于身份验证的Express中间件示例:
const tokenCheck = (req, res, next) => {
  let token = getToken(req);

  if (token) {
    jwt.verify(token, "password, (err, decoded) => {

      if (err) {
        throw "Failed to authenticate token.";
      } else {
        req.user = decoded;
        next();
      }
    });
  } else {
    throw "No token provided.";
  }
};

以这种方式使用:

router.get("/", tokenCheck, Controller.get);

所以每个路由都被一层身份验证保护。

关于微服务之间的通信,我读到最好的方法是使用API网关,我找到了这个库来实现它,此外我读到如果在每个单独的微服务中重新实现这些东西,会导致代码重复,更重要的是你有两个不同的软件来维护,因此最好将身份验证中间件添加到API网关中。

现在我的问题有两个:

1)使用这个API网关是否正确来实现微服务之间的通信?

2)如果将身份验证中间件从微服务移动到API网关,则必须从API路由中删除该中间件,这样,如果不是网关以外的人进行请求,API将不受保护。我认为这是错误的,因为任何人都可以调用那些路由。如果在微服务中保留中间件,代码就会重复,有没有人能告诉我正确的做法是什么?


很好的问题。 - Harshal Yeole
你能否批准下面的答案,如果它满足了你的问题,就关闭这个问题? - Harshal Yeole
1个回答

2

我已经从事Node.js工作了几年,以下是我的理解,希望这能帮助您澄清思路。

您的问题的答案:

让我向您解释一下您在问题中提到的两个部分的工作。

  • http-proxy-middleware

  • 您的自定义中间件

    • 您的自定义中间件是项目特定代码,用于检查所有请求是否经过身份验证。
    • 它将检查请求是否具有令牌以及令牌是否有效。

结论:

  • 您必须强制使用自定义中间件。另一个(http-proxy-middleware)是可选的。

更新:

现在我的问题有两个:

  1. 使用API网关进行微服务之间的通信是否正确?

答案:不,这不是正确的方法。

  1. 如果我将身份验证中间件从微服务移动到API网关,则必须从API路由中删除中间件,在这种方式下,如果除网关之外的其他人发出请求,则API将不受保护,我认为这是错误的,因为任何人都可以调用该路由,而如果我在mircorservice中也保留中间件,则代码会重复,有人能告诉我正确的方法吗?

对于此问题,您可以在应用程序上强制执行身份验证中间件,以便所有路由执行中间件。更新您的服务器代码。

// Init App
const App = Express();
// Authentication code
App.use((req, res, next) => {
let token = getToken(req);

  if (token) {
    jwt.verify(token, password, (err, decoded) => {

      if (err) {
        throw "Failed to authenticate token.";
      } else {
        req.user = decoded;
        next();
      }
    });
  } else {
    throw "No token provided.";
  }
});

谢谢您的回答,但我还没有理解它。所以您建议在每个微服务中添加身份验证中间件吗?我在网上找到了很多例子,他们解释将身份验证移动到API网关中。 - Piero
https://github.com/chimurai/http-proxy-middleware 是针对问题1的,其中我谈到了网关和网关与微服务之间的通信。我还没有理解您对于微服务通信的建议。 - Piero
对于第一条评论:我建议您保持代码不变,即将其作为中间件保存在API网关中。 - Harshal Yeole
不好意思,也许你还没有理解我的问题。我知道我可以在应用程序中应用中间件而不仅仅是单个路由,但你还没有回答我的问题:在每个微服务中复制代码是否正确?我必须在不同的地方维护它吗?至于第一个问题,你说API网关不是微服务通信的正确方式,那么你有什么建议呢? - Piero
不应该复制代码,这就是为什么我建议在应用程序上强制实施中间件。至于“API网关”,编辑服务器代码以创建代理并不好。你可以在部署级别上完成它,比如使用NGinx。你可以使用https://ngrok.com/来获取**公共URL**。 - Harshal Yeole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接