作为独立微服务进行身份验证的快速应用程序

时间:2019-07-09 06:18:49

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

当前情况:

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

我的最终用户正在使用nginx作为网络服务器来积极地处理作为docker容器托管的angular应用程序。

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

用户按角度登录,然后重定向到快速应用程序(相同的主机地址,只是另一个端点/ auth / someProvider)

快速应用程序没有用户界面,它只处理所有oauth重定向和与提供者的通信,在收集了用户信息之后,它将重定向回有角度的应用程序。

现在,这对于最后一部分很有效。当我的/ auth / provider / callback重定向到快速应用程序内部时,很容易访问已被用户对象扩展的请求对象。当我重定向到外部网站时,会获得Cookie和所有内容,但不是访问用户对象的简便方法。

我的主要问题:

有没有一种安全的方法可以直接从Request对象传递用户信息,以供有角度的应用程序使用(我可以想到的最佳方法是使用标头,因为标头也在https中进行了加密,但看起来还是有点hacky)。

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

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

1 个答案:

答案 0 :(得分:0)

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

基本上,您可以实现passport.js文档中描述的基本概念,并添加单独的端点来访问userinfo。这就是为什么我将描述它开始有所不同的地方

步骤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的块不是很漂亮,但是我碰巧所有这些组合都可能是不确定的

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

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

现在还需要注意一件事。如果要使用凭据来调用该API,将访问控制允许来源标头设置为*将不起作用。您将必须使用要从其呼叫的特定主机。另外,您将需要在标题中允许凭据。因此,请确保在主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();
});