在 NodeJS/Express 中使用 API 网关进行微服务 API 身份验证

Posted

技术标签:

【中文标题】在 NodeJS/Express 中使用 API 网关进行微服务 API 身份验证【英文标题】:Microservices API Authentication with API Gateway in NodeJS/Express 【发布时间】:2019-02-07 19:28:28 【问题描述】:

我正在使用 Node JS 和 Express 创建一个微服务架构。我知道微服务的主要特点之一是面向服务的架构,团队可以独立设计、开发和发布他们的应用程序。因此,在我的设计中,我认为每个微服务都提供它们的 API,并且它们通过 API 相互通信,每个微服务都是独立的,并且有自己的生命等待请求。

我写这个问题是因为我有几个疑问 微服务之间的身份验证和通信。

为了进行身份验证,我使用 JWT 进行了一些测试,以验证微服务的 API,一切正常,这是用于身份验证的快速中间件示例:

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 网关,我发现 this 库可以做到这一点,此外,我读到最好在 API 网关中添加身份验证中间件,因为如果你重新-在每一个微服务中实现这些东西,一开始你是在复制代码,但更重要的是你有两个不同的软件需要维护。

现在我的问题是两个:

1) 微服务​​之间是否可以使用this这样的API网关进行通信?

2) 如果我将身份验证中间件从微服务移动到 API 网关,我必须从 API 路由中删除中间件,这样如果网关以外的人发出请求,API 将不受保护,我认为这是错了,因为任何人都可以调用该路由,而不是如果我维护中间件也是 mircorservice 代码重复,谁能告诉我正确的方法是什么?

【问题讨论】:

好问题。 您能否批准以下答案,如果它满足您的问题,则关闭该问题? 【参考方案1】:

过去几年我一直在研究 Node.js,这是我的理解,希望这能帮助您理清思路。

你的问题的答案:

让我向你解释你在问题中陈述的两个部分的工作。

http-proxy-middleware

代理:简单来说,代理就是复制克隆,也可以转你的流量。 阅读更多:What is the proxy server?

您的客户中间件

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

结论:

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

更新:

现在我的问题是两个:

    是否正确使用这样的 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 网关中移动身份验证的示例。 github.com/chimurai/http-proxy-middleware 是针对问题 1 讲的网关以及网关与微服务之间的通信,我也没有明白你对微服务通信的建议 第 1 条评论:我建议您保持代码原样,这意味着将其作为中间件保存在 API 网关中。 不,也许你没有理解我的问题,我知道我可以在应用程序上应用中间件,而不仅仅是在单一路由上,但你没有回答我的问题是正确的在每个微服务中复制代码?我必须在不同的地方维护它?对于这个问题,您感到遗憾的是,用于微服务通信的 API 网关不是正确的方式,您的建议是什么? 复制代码是不对的,这就是为什么我要在应用程序上强加中间件。而对于“API GATEWAY”,编辑您的服务器代码以创建代理并不好。您绝对可以在部署级别做到这一点。也许使用nginx。您可以将ngrok.com 用于公共网址

以上是关于在 NodeJS/Express 中使用 API 网关进行微服务 API 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS Express API 调用结构异步事件

使用异步和请求包(NodeJS / Express)进行多个 API 调用

NodeJS/express - 公共 API 端点的安全性

NodeJs+Express+SqlServer简易后台API服务搭建

API 中未显示数据(NodeJS + Express)

如何验证从反应 SPA 中的 keycloak 检索的 nodejs express api 的访问令牌?