Я разрабатываю угловой 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);
};
}
Я новичок в веб-программировании и, что удивительно, не смог найти пример для приведенного выше сценария. Все примеры либо все угловые, либо все узлы, но не смешанные. Очевидно, у меня есть неправильные представления о механизмах экспресс и управления пользователями с паспортом.
Мои вопросы
Как правило, не рекомендуется запускать Angular и Node в разных доменах для этого типа аутентификации?
Где в паспорте находится идентификатор пользователя (oid)? В печенье? Если да, могу ли я отследить это в объектах ответа / запроса Express? Если это файл cookie, могу ли я передать файл cookie в другой домен? Или мне нужно передать oid в параметре запроса клиенту и вручную установить cookie на стороне клиента с соответствующими параметрами?
Является ли общая структура аутентификации пользователя неправильной? Нужно ли использовать 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'}))