Как управлять идентификатором пользователя в угловых и узел для пользователя, вошедшего в Azure с помощью графика API - PullRequest
0 голосов
/ 12 мая 2019

Я разрабатываю угловой 7-интерфейс и серверный узел node.js / express, который использует API-интерфейс graph Microsoft. Фронт и бэкэнд находятся на разных доменах. Для авторизации я использую passport.js с OIDCStrategy. Могу ли я использовать механизм passport serializeUser / deserializeUser, чтобы идентифицировать пользователя и связанный с ним сеанс?

На бэкенде в узле, когда авторизация OID завершена, я бы хотел перенаправить на внешний интерфейс

// Node
router.post('/callback',
  function(req, res, next) {
    passport.authenticate('azuread-openidconnect',
      {
        response: res,
        failureRedirect: '/api',
        failureFlash: true
      }
    )(req,res,next);
  },
  function(req, res) {
    res.redirect('http://localhost:4200/home'); // => angular front end
  }

В этот момент в потоке управления паспорт добавил пользовательский oid к сеансу в объекте запроса, т. Е. req.session.passport содержит пользовательский oid. Вероятно, это делается в функции serializeUser ниже

// Node
passport.serializeUser(function(user, done) {
  // Use the OID property of the user as a key
  users[user.profile.oid] = user;
  done (null, user.profile.oid);
});

passport.deserializeUser(function(id, done) {
  done(null, users[id]);
});

Однако в объекте ответа пользовательский oid отсутствует. Я предполагал, что паспорт помещает oid в cookie, так что в следующем запросе пользовательский oid может быть присоединен к req.user, но это не то, что я вижу здесь.

На принимающей стороне перенаправления, когда в угловом компоненте маршрута / home я использую сервис cookie, чтобы узнать, нет ли oid

// Angular 
ngOnInit() {
    // there is nothing valuable in the cookie
    console.log(this.cookie.get('passport'));

    // from here on i'd like to make requests to the graph api
    this.iGraphService.getNotebooks().subscribe((result) => {
      console.log("Getting the Notebook: " + result.name);
    }), (error) => {
      console.log("Not Receiving Notebook" + error);
    };
  }

Я новичок в веб-программировании и, что удивительно, не смог найти пример для приведенного выше сценария. Все примеры либо все угловые, либо все узлы, но не смешанные. Очевидно, у меня есть неправильные представления о механизмах экспресс и управления пользователями с паспортом.

Мои вопросы

  1. Как правило, не рекомендуется запускать Angular и Node в разных доменах для этого типа аутентификации?

  2. Где в паспорте находится идентификатор пользователя (oid)? В печенье? Если да, могу ли я отследить это в объектах ответа / запроса Express? Если это файл cookie, могу ли я передать файл cookie в другой домен? Или мне нужно передать oid в параметре запроса клиенту и вручную установить cookie на стороне клиента с соответствующими параметрами?

  3. Является ли общая структура аутентификации пользователя неправильной? Нужно ли использовать JWT для передачи идентификатора пользователя и идентификации пользователя вне паспорта?

Редактировать

После прочтения сеансов и файлов cookie, я полагаю, что файл cookie записан в промежуточном программном обеспечении экспресс-сеанса, т.е. Теперь, когда я смотрю, что происходит в этом примере, прямо перед перенаправлением на угловой интерфейс, я обнаруживаю, что сессия req.session выглядит разумно:

Session {cookie: Cookie, flash: Object, OIDC: XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX: Object, passport: Object, req: IncomingMessage, …}

Однако файл cookie req.session.cookie выглядит недостаточно четко:

Cookie {path: "/", _expires: null, originalMaxAge: null, httpOnly: true}
_expires:null
data:   Object
        expires:null
        httpOnly:trueMaxAge:null
        path:"/"
        sameSite:undefined
        secure:undefined
expires:null
httpOnly:true
maxAge:null
originalMaxAge:null
path:"/"

Это даже не те значения, которые я указал в конфигурации.

Редактировать 2

Решением является указание httpOptions.

    const httpOptions = {
      withCredentials: true,
    };
    return this.httpClient.get<INotebookInfo>('http://localhost:3000/api/...', httpOptions);

Затем файл cookie успешно отправляется на сервер. Однако с включенным withCredentials: true, чтобы избежать проблем с cors при использовании пакета cors, сделайте что-то вроде

app.use(cors({credentials: true, origin: 'http://localhost:4200'}))
...