Ошибочный повторный ответ сервера
Пишу свой мессенджер и столкнулся с проблемой в ситуации когда при логине у меня отправляется запрос на проверку пользователя и на создание jwt-токена, но по какой-то причине приходит два ответа от него с задержкой буквально несколько миллисекунд: 1 - правильный, где записан id и токен авторизованного пользователя, а 2 - ошибочный, которого вообще не должно возникать, который имеет пустой массив данных и код успешности. Программа начинает обрабатывать второй ответ вместо первого и выдает ошибку о некорректности данных от сервера.
Сервер написан на nodejs данные берутся из бд(mongodb, если это на что-то влияет):
const express = require('express');
const mongoose = require('mongoose');
const dotenv = require('dotenv');
dotenv.config({ path: "./Config.env" });
const writeUri = require('./dbConnection');
const cors = require('cors');
const { generateSalt, hashPassword, validatePassword } = require('./security/crypt');
const { EmailValid } = require("./processingServer/ChekingEmail");
const CreateJWT = require("./security/Create_jwt");
const Dialogs = require("./ChatLogic/SearchAllChats");
const User = require('./modules/Users');
const app = express();
const PORT = 8080;
app.use(express.json());
app.use(cors({
origin: 'http://localhost:3000',
methods: ['POST']
}));
// Подключение к MongoDB
mongoose.connect(writeUri, {
}).then(() => {
console.log('Подключено к MongoDB');
}).catch((error) => {
console.error('Ошибка подключения к MongoDB:', error);
});
const isEmailUnique = async (email) => {
try {
const user = await User.findOne({ email: email });
return !user;
} catch (error) {
console.log("Ошибка сервера", error)
}
};
app.post("/api/check-user", async (req, res) => {
const { email, password } = req.body;
try {
const user = await User.findOne({ email }).select({ salt: 1, password: 1, name: 1, _id: 1 }).lean();
if (!user) {
console.log("User not found");
return res.status(400).json({ success: false, message: 'Пользователь не найден' });
}
const isValid = validatePassword(password, user.password, user.salt);
if (!isValid) {
console.log("Invalid password");
return res.status(400).json({ success: false, message: 'Неверный логин или пароль' });
}
const JWT_token = await CreateJWT(user._id, user.name);
const updatedUser = await User.findByIdAndUpdate(user._id, { Jwt: JWT_token }, { new: true }).lean();
console.log("Updated User:", updatedUser);
if (!updatedUser) {
console.log("Error updating token");
return res.status(500).json({ success: false, message: 'Ошибка обновления токена' });
}
console.log("Sending success response");
return res.status(200).json({
success: true,
message: 'Добро пожаловать!',
token: JWT_token,
id: updatedUser._id.toString(),
});
} catch (error) {
console.error('Ошибка при проверке пользователя:', error);
return res.status(500).json({ success: false, message: 'Ошибка сервера' });
}
});
app.post("/api/create-user", async (req, res) =>{
const {UserName, email, password} = req.body;
// Проверка валидности email
if (!EmailValid(email)) {
return res.status(402).json({ success: false, message: 'Некорректный формат электронной почты' });
}
else
isEmailUnique();
// Проверка уникальности email
if (!(await isEmailUnique(email))) {
return res.status(403).json({ success: false, message: 'Электронная почта уже используется' });
}
const CreateSalt = generateSalt();
const HashedPaswd = hashPassword(password, CreateSalt);
const newUser = new User({
name: UserName,
email: email,
password: HashedPaswd,
salt: CreateSalt,
Jwt: ''
})
try {
await newUser.save();
console.log("Пользователь успешно создан!")
} catch (error) {
console.log("Произошла ошибка создания пользователя", error)
}
})
app.post('/api/SearchAllUnikChats', async (req, res) => {
const { JwtToken, Userid } = req.body;
try {
const user = await User.findOne({ Jwt: JwtToken }).lean();
if (user) {
const FindDialogs = await Dialogs(Userid);
res.status(200).json({ success: true, FindDialogs });
} else {
res.status(403).json({ success: false, message: 'Ошибка в токене' });
}
} catch (error) {
console.error("Ошибка поиска диалогов:", error);
res.status(500).json({ success: false, message: 'Ошибка сервера' });
}
});
// Запуск сервера
app.listen(PORT, () => {
console.log(`Сервер запущен на http://127.0.0.1:${PORT}`);
});
module.exports = {User};
И код клиентской части, в которой происходит вся эта тема(React Native expo):
const handleMessage = useCallback(async (event) => {
try {
console.log("Raw event data:", event.data); // Логируем сырые данные
const response = JSON.parse(event.data);
console.log("Parsed response:", response); // Логируем разобранные данные
if (response.success) {
if (response.token && response.id) { // Проверяем наличие token и id
console.log(response);
try {
await AsyncStorage.setItem('JwtToken', response.token);
await AsyncStorage.setItem('_id', response.id);
Alert.alert("Успешно", response.message);
navigation.replace("MainMenu");
} catch (error) {
console.log(error);
Alert.alert("Не сохранило данные.");
}
} else {
console.log("Server res: ", response);
Alert.alert("Ошибка", "Некорректные данные с сервера.");
}
} else {
Alert.alert("Ошибка", response.message);
if (response.message === "неверный логин или пароль" && formikRef.current) {
formikRef.current.setFieldValue('password', ''); // Очищаем поле пароля
}
}
} catch (e) {
console.error('Ошибка при разборе сообщения:', e, event.data);
}
}, [navigation]);
React.useEffect(() => {
if (socket) {
socket.addEventListener('message', handleMessage);
return () => {
socket.removeEventListener('message', handleMessage);
};
}
}, [socket, handleMessage]);
Есть также промежуточный сервер на WebSoket, но вроде дело не в нем, но прикреплю на всякий случай, если проблема все-таки в нем:
import express from 'express';
import http from 'http';
import { WebSocketServer } from 'ws';
import axios from 'axios';
import dotenv from 'dotenv';
import messageHandlers from './processingMessages/GeneralProc.js';
dotenv.config({ path: "./Config.env" });
const app = express();
const PORT = 3000;
const server = http.createServer(app);
// Создаем WebSocket сервер
const wss = new WebSocketServer({ server });
wss.on('connection', (ws) => {
console.log('Новое WebSocket-соединение установлено');
ws.on('message', async (message) => {
try {
const data = JSON.parse(message.toString());
const hendler = messageHandlers[data.type];
if(hendler)
hendler(ws, data);
else
ws.send(JSON.stringify({success: false, message: "Тип запроса не найден"}));
} catch (error) {
console.error('Ошибка при обработке данных:', error.message);
ws.send(JSON.stringify({ success: false, message: 'Ошибка при обработке данных' }));
}
});
ws.on('close', (code, reason) => {
console.log(`Соединение закрыто. Код: ${code}, Причина: ${reason}`);
});
});
// Запуск сервера
server.listen(PORT, (err) => {
if (err) {
console.error('Ошибка при запуске сервера:', err);
} else {
console.log(`Сервер запущен на http://localhost:${PORT}`);
}
});
export default server;
Сам логин в websoket
import axios from 'axios';
async function LoginCheck(ws, { email, password }) {
try {
const response = await axios.post(process.env.URL_CHECK_USER, { email, password });
ws.send(JSON.stringify(response.data)); // Успешный ответ клиенту
} catch (err) {
console.error('Ошибка при отправке запроса:', err.message);
ws.send(JSON.stringify({ success: false, message: 'Неверный логин или пароль' }));
}
}
export default LoginCheck;
messageHandlers - просто функция определяющая тип запроса и ничего более
тут немного пояснения что я вижу в консоли приложения, когда приходит ответ от сервера