У вас есть две вложенные асинхронные операции (здесь показано упрощенно), а затем вы пытаетесь выполнить что-то последнее в первом обработчике .then()
:
Issuer.discover().then(function() {
client.callback().then(function() {
// ...
});
res.redirect('/oidc-callback');
});
Это вызывает вызов res.redirect()
до client.callback()
сделано, поскольку в вашем коде нет ничего, что заставляло бы его ждать завершения client.callback()
.Это отправляет ответ и вызывает перенаправление перед изменением сеанса, а это не то, что вы хотите сделать.Это можно исправить одним из двух способов:
1) Поместите res.redirect()
во внутреннюю .then()
следующим образом:
Issuer.discover().then(function() {
client.callback().then(function() {
// ...
res.redirect('/oidc-callback');
});
});
2) Добавьте return
перед client.callback()
так, чтобы оно связало внутреннее обещание с внешним.Тогда внешний не будет завершен, пока не завершится внутренний, и вы можете добавить еще один обработчик .then()
, чтобы поместить res.redirect()
в:
Issuer.discover().then(function() {
return client.callback().then(function() {
// ...
});
}). Then (function () {// вызывается, когда выполняются обе асинхронные операции res.redirect ('/ oidc-callback');});
Я бы порекомендовал вариант № 2, поскольку он упрощает обработку ошибок, поскольку вы можете выполнять все своиобработка ошибок в одном месте на верхнем уровне.Собрав все это вместе, вы получите следующее:
router.get('/api/oidc-callback', (req, res, params) => {
Issuer.discover('http://localhost:5000').then(function(identityIssuer) {
const client = new identityIssuer.Client({
...
})
return client.callback('http://localhost:3000/api/oidc-callback', req.query, {
code_verifier
}).then(function(tokenSet) {
console.log(req);
req.session.token = tokenSet.access_token
}, req);
}).then(() => {
res.redirect('/oidc-callback');
}).catch(err => {
console.log(err);
res.sendStatus(500);
});
});
Обратите внимание, в конце я также добавил правильную обработку ошибок.Это гарантирует, что ответ не будет отправлен до тех пор, пока не будут выполнены обе ваши асинхронные операции, и в случае сбоя одного из них он отправит правильный ответ об ошибке.