node.js - 将身份验证快速应用为单独的微服务

标签 node.js docker express get passport.js

当前情况:

我目前正在与特定的 oauth 提供商合作,并将我的应用程序作为微服务托管在 kubernetes 集群中。

我的最终用户正在积极使用作为 Docker 容器托管的 Angular 应用程序,使用 nginx 作为网络服务器。

现在我的想法是使用 Node.js Express 和 Passport 将身份验证集成为单独的微服务。所以工作流程是

用户以角度登录并被重定向到 Express 应用程序(相同的主机地址,只是不同的端点/auth/someProvider)

express 应用程序没有用户界面,它只是处理所有 oauth 重定向以及与提供商的通信,在收集用户信息后,它会重定向回 Angular 应用程序。

现在这对于最后一部分来说非常有效。当我的/auth/provider/callback 将在 Express 应用程序内部重定向时,可以很容易地访问已使用用户对象扩展的请求对象。当我重定向到外部网站时,我得到了 cookie 和所有内容,但不是访问用户对象的简单方法。

我的实际问题:

有没有一种安全的方法可以直接从请求对象传递用户信息以供角度应用程序使用(我能想到的最好方法是使用 header ,因为它们也在 https 中加密,但仍然看起来有点黑客)。

以这种方式使用 OAuth 通常是个好主意吗?

此解决方案的一大优点是,我可以在许多 Web 项目中使用相同的 Docker 容器,而无需通过更改该 Docker 容器中的 ClientId 和 Secret Env Vars 来一一实现身份验证。

最佳答案

好的,这就是我的工作方式。

基本上,您实现了 Passport.js 文档中描述的基本概念,并添加一个单独的端点来访问用户信息。这就是为什么我将描述它开始有所不同的地方

第 1 步:在网关验证用户身份

如 Passport.js 文档中所述。身份验证微服务需要以下回调(这里的路由器已经在/auth下提供服务)

router.get("/provider/callback", passport.authenticate("provider", {
  failureRedirect: "https://your-frontent-app.com/login",
}), (req, res) => {
  res.redirect("https://your-frontend-app.com");
});

当您返回 Web 应用程序时,您将看到 session Cookie 已成功存储。

第2步:从端点获取用户信息

现在我们的路由中需要第二个端点/auth/userinfo。

router.get('/userinfo', (req, res) => {
  if(!req.session) return res.status(401).send();
  if(!req.session.passport) return res.status(401).send();
  if(!req.session.passport.user) return res.status(401).send();
  return res.json(req.session.passport.user).status(200).send();
});

这个带有 3 个 if 的 block 不太漂亮,但我碰巧所有这些组合都可能是未定义的

现在,通过存储在浏览器中的 session cookie,我们可以使用凭据从前端调用该端点(我将使用 axios)

axios.get('https://your-authenticator.com/auth/userinfo', {withCredentials: true})
  .then(res => {
    //do stuff with res.data
  });

现在还有一件事需要注意。如果您想使用凭据调用该 API,则将 Access-Control-Allow-Origin header 设置为 * 将不起作用。您必须使用您要调用电话的特定主机。此外,您还需要允许 header 中的凭据。因此,回到您的主 Express 应用程序中,请确保使用诸如

之类的标题
app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "https://your-frontend-app.com");
  res.header("Access-Control-Allow-Credentials", "true");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Auth, Authentication, Authorization, Credentials");

  next();
});

关于node.js - 将身份验证快速应用为单独的微服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56946369/

相关文章:

javascript - 从 Node API 到 PHP 服务器的 Axios 调用导致套接字挂起

Docker 不使用代理运行

java - 从 docker 镜像运行 Maven 命令

bash - Bash:从docker-compose.yml获取容器名称列表

javascript - 如何将从 Controller 返回的数据传递到 Express 路由器?

node.js - 通过 RTMP 的 NodeJS 和 RED 5 媒体服务器

javascript - 在 node.js 中使用 chart.js

javascript - 如何从 mongoDB 中分离字符串

node.js - 如何使用 Playwright 最大化弹出窗口(例如单击按钮打开弹出窗口)

node.js - 生产中的 MongoDB 查询(身份验证)不起作用