#javascript #node.js #express
#javascript #node.js #выразить
Вопрос:
Я разрабатываю серверную часть для мобильного приложения, используя express.js для моего API.
Для этого мобильного приложения пользователи входят в систему, используя номера мобильных телефонов, на их мобильные телефоны отправляется код OTP, и им необходимо отправить полученный OTP обратно на сервер для проверки и валидации.
Когда пользователи впервые пытаются войти в систему, они ОТПРАВЛЯЮТ свой номер мобильного телефона на сервер, а затем происходит куча обработки, и им отправляется OTP через SMS-шлюз.
Теперь, пока этот запрос все еще выполняется, мне нужно дождаться, пока пользователи отправят OTP через POST-запрос на другой маршрут, проверят его, а затем продолжат соответствующие шаги в первом, текущем POST-запросе.
После некоторого поиска в сети я в конце концов решил обернуть метод app.post для маршрута verifyOTP в функцию, которая создает и возвращает новое обещание, а затем разрешает его или отклоняет после проверки. Это сработало чудесно, когда я впервые выполняю эту операцию после перезапуска сервера, но это все. Это работает только в первый раз, а затем в последующие разы ни одно из новых обещаний, которые должны быть созданы, не разрешается или не отклоняется, и первый запрос на маршрут входа остается ожидающим.
Я пробовал кучу вещей, таких как создание функции, обертывающей маршрут verifyOTP асинхронно, и создание обещаний внутри маршрута вместо того, чтобы обертывать его в одном, но все равно бесполезно. Вы можете мне помочь?
Ради поиска решения этой проблемы я упростил процесс и сделал симуляцию реальной ситуации с использованием этого кода, и он хорошо имитирует проблему:
Это для имитации первого запроса:
app.get("/test", async function(req, res) {
console.log("Test routen");
var otpCode = Math.floor(Math.random() * (9999 - 2)) 1;
var timestamp = Date.now();
otp = {
code: otpCode,
generated: timestamp
};
console.log("OTP code sent: " otpCode "n");
console.log("OTP sent.n");
res.end();
/* verifyOTP().then(function() {
console.log("Resolved OTP verificationnn");
res.end();
}).catch(function() {
console.log("Badnn");
res.end();
});*/
});
Это маршрут verifyOTP:
var otp;
app.post("/verifyOTP", function(req, res) {
console.log("POST request - verify OTP requestn");
var msg;
if ((Date.now() - otp.generated) / 1000 > 30) {
msg = "OTP code is no longer valid.";
res.status(403).json({
error: msg
});
} else {
var submitted = req.body.otp;
if (submitted !== otp.code) {
msg = "OTP code is incorrect.";
res.status(403).json({
error: msg
});
} else {
msg = "Verified.";
res.end();
}
}
console.log(res.statusCode " - " res.statusMessage "n");
console.log(msg "n");
});
Просто упомяну, что это не единственное место на моем сервере, где мне нужна проверка OTP, хотя реализация того, что происходит после проверки, варьируется. Поэтому я был бы признателен, если бы решение могло по-прежнему использовать код повторно для нескольких экземпляров..
Комментарии:
1. Хотя это технически возможно сделать таким образом, это ужасная идея, которая отнимет много времени, когда время ожидания браузера истекает до того, как пользователь отправит OTP. Делайте то, что делают все остальные: отвечайте, сообщая пользователю, что ему нужен код OTP, и предоставляя форму для его ввода. Затем продолжайте путь с ответом на получение кода.
2. Спасибо, я попробую это .. Я постараюсь сделать его повторно используемым для нескольких случаев, для которых мне нужна проверка OTP..
3. Бесполезно. Это только что создало массу других ошибок при подключении к базе данных и отправке ответа..
Ответ №1:
Что ж, после еще нескольких собственных исследований я отказался от использования Promises для этого варианта использования все вместе и вместо этого использовал наблюдаемые RxJS..
Это решило мою проблему в значительной степени так, как я этого хочу, хотя мне пришлось внести некоторые небольшие изменения..
Для тех, кто натыкается на мой вопрос в поисках решения той же проблемы, с которой я столкнулся:
Обещания могут быть разрешены или отклонены только один раз, и, насколько я могу судить, если функция Promises не завершит выполнение, вы не сможете создать новую с тем же кодом (пожалуйста, поправьте меня, если я ошибаюсь в этом, я был бы очень признателен, это было основано только на моих личных наблюдениях и догадках), и если вы не создадите совершенно новое обещание, вы не сможете разрешить его снова.
В этом случае мы создаем обещание из прослушивателя (или как бы он ни назывался в js), поэтому, если вы не удалите прослушиватель, функция, измененная внутри обещания, не завершит выполнение (я думаю), и вы не сможете создать новое обещание.
Наблюдаемые, с другой стороны, можно повторно использовать столько раз, сколько вы хотите, смотрите Это для сравнения между Promises и наблюдаемыми, а это — для хорошего руководства, которое поможет вам понять наблюдаемые и как их использовать. Смотрите это, как установить RxJS для узла.
Однако имейте в виду — по какой-то причине, как только вы подписываетесь на observable, переменные, используемые в функции, переданной observable.subscribe(), остаются неизменными, они не обновляются с каждым новым запросом, который вы отправляете на маршрут наблюдателя. Поэтому, если вы не найдете способ передать переменные, которые изменяются, в функцию observer.next() внутри наблюдаемого определения, вы получите неправильные результаты.