【问题标题】:Express application for Authentication as seperate microservice将身份验证的快速应用程序作为单独的微服务
【发布时间】:2019-07-09 06:18:49
【问题描述】:

现状:

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

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

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

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

express 应用程序没有用户界面,它只处理所有的 oauth 重定向和与提供者的通信,在收集到用户信息后,它会重定向回 angular 应用程序。

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

我的尖锐问题:

是否有一种安全的方法可以将请求对象中的用户信息直接传递给 angular 应用程序使用(我能想到的最好方法是使用标头,因为它们在 https 中也是加密的,但似乎仍然有点哈克)。

一般来说,以这种方式使用 OAuth 是否是个好主意。

此解决方案的最大优势在于,我可以将同一个 Docker 容器与许多 Web 项目一起使用,而不必通过更改该 Docker 容器中的 ClientId 和 Secret Env Vars 来一一实现身份验证。

【问题讨论】:

    标签: node.js docker express get passport.js


    【解决方案1】:

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

    基本上,您实现了 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 步:从 Endpoint 获取用户信息

    现在我们的路由中需要第二个端点 /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 的块不是很漂亮,但我碰巧所有这些组合都可能是未定义的

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

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

    现在还有一件事要注意。如果您想使用凭据调用该 API,则将 Access-Control-Allow-Origin 标头设置为 * 将不起作用。您将不得不使用您将从中调用的特定主机。此外,您还需要在标头中允许凭据。所以回到你的主要 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();
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-02
      • 2019-10-02
      • 2021-03-31
      • 2018-07-17
      • 1970-01-01
      • 2020-09-25
      • 2022-06-11
      相关资源
      最近更新 更多