使用 JWT 对单独的 API 微服务进行身份验证
Posted
技术标签:
【中文标题】使用 JWT 对单独的 API 微服务进行身份验证【英文标题】:Use JWT to authenticate separate API Microservice 【发布时间】:2019-10-02 11:25:41 【问题描述】:我正在使用 NodeJS 中的微服务开发应用程序。我已经构建了一个 auth api,它处理通常的注册登录等,它发出 JWT 的
如何使用这些来保护使用 Express 编写的单独 API 微服务中的路由?
我是否需要使用 JWT 和 Secret 来解密 API 应用程序中的令牌?
【问题讨论】:
这种方式太复杂了,也违背了单一职责的原则。基本反向代理解决问题 【参考方案1】:这里的一个常见模式是使用 API 网关作为整个微服务架构的入口点。传入的身份验证请求将被路由到适当的微服务。如果提供的凭证是正确的,一个新的 JWT 将返回到网关,然后转发给调用者。对于构成您的应用程序的实际微服务 API,网关会在允许请求命中微服务之前检查传入的 JWT 是否有效。
为简单起见,此答案省略了一些内容。例如,您通常希望拥有一个授权微服务,它决定允许用户做什么。此外,还可能涉及实现 JWT。您可能需要一个缓存层来跟踪列入白名单和/或列入黑名单的 JWT。
【讨论】:
不会造成单个API网关的瓶颈吗?【参考方案2】:您可以编写一个导入到其他微服务中的库,默认情况下要求所有路由都需要身份验证。这个库可以有一种机制来在微服务级别验证 JWT,所以你永远不需要与你的 auth api 交谈来查看 JWT 是否有效。请参阅下面的描述和图表:
您的身份验证服务器将需要成为您的微服务的 JWT 的单一发行者。因此,当用户登录并成功进行身份验证时,您的身份验证服务器将发出一个使用私钥签名的 JWT(签名必须是非对称的 - RS256 就是一个示例),您只保留在身份验证服务器上;不要将此私钥提供给您希望在其中验证 JWT 的其他微服务。您可以做的是根据您签署令牌的私钥派生一个公钥,并将其发布到不需要身份验证的身份验证服务器上的端点 - 公钥将以JWK 的形式表示(请参阅链接到规范)。谷歌做了类似的事情here。然后,在您的每个微服务中,您的库将需要设计一种方法,每 X 分钟向您的身份验证服务器上的公钥端点发出 GET 请求,以查看是否有任何更改并缓存每个微服务中的公钥。通过将公钥缓存在您的微服务中,您将能够在被请求的服务中验证请求的 JWT。
然后,每当请求进入您的一个微服务时,您导入的库将检查请求的 JWT,检查其有效性,并在令牌有效时授予访问/授权。使用私钥/公钥对和非对称密钥签名的美妙之处在于,您可以仅根据公钥验证令牌,但不能对其进行签名。因此,只要每个服务都拥有来自您的 /cert 端点的公钥,它们就可以验证令牌,而无需与身份验证服务器对话或知道私钥。
这将需要更多的前期工作,但知道只有一个来源知道您的私钥,将来会为您带来大量的轻松、灵活性和安心。
【讨论】:
这种通用库的缺点是,对库的任何更改都会导致所有微服务都需要拉升级+重新部署。当您只调用身份验证微服务时,不需要这样做。 @Chappie Johnson 你能提供一些描述相同流程的链接或演示项目吗? 如果您的所有微服务都使用相同的后端语言,则很容易,但如果不使用,则需要大量工作。通常需要为每个服务利用最好的语言,这是微服务的优点之一以上是关于使用 JWT 对单独的 API 微服务进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章
JWT 是不是应该是一个单独的身份验证微服务,而不是与后端业务逻辑坐在一起?