Экспресс приложение для аутентификации как отдельный микросервис - PullRequest
1 голос
/ 09 июля 2019

Текущая ситуация:

В настоящее время я работаю с конкретным провайдером oauth и размещаю свои приложения в виде микросервисов в кластере kubernetes.

Мой конечный пользовательактивно работаю с угловым приложением, размещаемым в качестве док-контейнера, используя nginx в качестве веб-сервера.

Теперь моя идея заключалась в том, чтобы интегрировать аутентификацию в качестве отдельного микросервиса с использованием node.js express и passport.таким образом, рабочий процесс будет

Пользователь нажимает на вход в систему под углом и перенаправляется в приложение Express (тот же адрес хоста, только на другую конечную точку / auth / someProvider)

Приложение Express не имеет пользовательского интерфейса.просто обрабатывает все перенаправления oauth и связь с провайдером, после сбора пользовательской информации он перенаправляет обратно в угловое приложение.

Теперь это работает довольно для последней части.Когда мой / auth / provider / callback перенаправляет внутри приложения Express, очень легко получить доступ к объекту запроса, который был расширен с помощью объекта пользователя.когда я перенаправляю на внешний веб-сайт, я получаю cookie и все, но не простой способ получить доступ к объекту пользователя.

Мой точный вопрос (ы):

есть безопасный способ передать эту пользовательскую информацию из объекта Request непосредственно для использования угловым приложением (лучший способ, о котором я мог подумать, - это использовать заголовки, так как они также зашифрованы в https, но все еще кажутся хакерскими). ​​

Является ли вообще хорошей идеей использовать OAuth таким образом.

Большим преимуществом этого решения было бы то, что я мог бы использовать один и тот же Docker-контейнер со многими веб-проектами, не требующими реализации Аутентификации по одному.один, просто изменив ClientId и Secret Env Vars в этом Docker-контейнере.

1 Ответ

0 голосов
/ 10 июля 2019

ОК, вот как я это сделал.

В основном вы реализуете базовую концепцию, описанную в документации 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");
});

Когда вы вернетесь в свое веб-приложение, вы увидите, что 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 если, но мне случилось, что все эти комбинации могут быть неопределенными

Теперь, сессионный 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();
});
...