#javascript #node.js #mongodb #express #reactjs
#javascript #node.js #mongodb #выразить #reactjs
Вопрос:
В моем проекте ReactJS я в настоящее время запускаю сервер с помощью NodeJS и ExpressJS и подключаюсь к MongoDB с помощью MongoClient. У меня настроена конечная точка API входа в систему, которая принимает запрос с именем пользователя и паролем пользователя. И если пользователь не найден, следует перехватить ошибку и ответить с ошибкой ( status(500)
) интерфейсу.
Но вместо того, чтобы отвечать на интерфейс с ошибкой json, сервер выходит из строя. Я перепробовал все, чтобы выяснить, почему, но все равно безуспешно.
Как я могу исправить следующую ошибку? Любое руководство или понимание будет высоко оценено, и мы поддержим и примем ответ.
Я намеренно сделал запрос с именем пользователя и паролем ( { username: 'iopsert', password: 'vser'}
), которых не существует в базе данных.
Вот конечная точка входа в систему:
//login endpoint
app.post('/api/login/', function(req, res) {
console.log('Req body in login ', req.body)
console.log('THIS IS WHAT WAS PASSED IN ', req._id)
db.collection('users').findOne({username: req.body.username}, function(err, user) {
console.log('User found ')
if(err) {
console.log('THIS IS ERROR RESPONSE')
// Would like to send this json as an error response to the front-end
res.status(500).send({
error: 'This is error response',
success: false,
})
}
if(user.password === req.body.password) {
console.log('Username and password are correct')
res.status(500).send({
username: req.body.username,
success: true,
user: user,
})
} else {
res.status(500).send({
error: 'Credentials are wrong',
success: false,
})
}
})
А вот журнал ошибок терминала:
Req body in login { username: 'iopsert', password: 'vset' }
THIS IS WHAT WAS PASSED IN undefined
User found
/Users/John/practice-project/node_modules/mongodb/lib/utils.js:98
process.nextTick(function() { throw err; });
^
TypeError: Cannot read property 'password' of null
at /Users/John/practice-project/server/server.js:58:12
at handleCallback (/Users/John/practice-project/node_modules/mongodb/lib/utils.js:96:12)
at /Users/John/practice-project/node_modules/mongodb/lib/collection.js:1395:5
at handleCallback (/Users/John/practice-project/node_modules/mongodb/lib/utils.js:96:12)
at /Users/John/practice-project/node_modules/mongodb/lib/cursor.js:675:5
at handleCallback (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:165:5)
at setCursorNotified (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:505:3)
at /Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:578:16
at queryCallback (/Users/John/practice-project/node_modules/mongodb-core/lib/cursor.js:226:18)
at /Users/John/practice-project/node_modules/mongodb-core/lib/connection/pool.js:430:18
И /Users/John/practice-project/node_modules/mongodb/lib/utils.js:98
имеет в виду следующее:
var handleCallback = function(callback, err, value1, value2) {
try {
if(callback == null) return;
if(value2) return callback(err, value1, value2);
return callback(err, value1);
} catch(err) {
process.nextTick(function() { throw err; });
return false;
}
return true;
}
Редактировать
Вот все, что импортируется на сервер:
"use strict"
var express = require('express');
var path = require('path');
var config = require('../webpack.config.js');
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var bodyParser = require('body-parser');
var MongoClient = require('mongodb').MongoClient;
var ObjectId = require('mongodb').ObjectID;
const jwt = require('jsonwebtoken')
var app = express();
var db;
var compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));
app.use(webpackHotMiddleware(compiler));
app.use(express.static('dist'));
app.use(bodyParser.json());
И именно так выполняется запрос и обнаруживается ошибка:
loginUser(creds) {
var request = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(creds),
}
fetch(`http://localhost:3000/api/login`, request)
.then(res => res.json())
.then(user => {
console.log(user);
console.log('Successful')
})
.catch(err => {
console.log('Error is', err)
})
},
Комментарии:
1. Кажется
user
илиreq.body
не определено, включили ли вы анализатор тела в свой проект.2. @adeneo Да, пожалуйста, взгляните на редактирование в исходном сообщении. Когда я передаю запрос с именем пользователя и паролем, которые существуют,
user
регистрируются правильныеreq.body
и и вводится оператор if.
Ответ №1:
Мне кажется, что ошибка выдается в этой строке, потому user
что не определена.
if(user.password === req.body.password) {...}
Внимательно посмотрите на свои консольные инструкции.
1. Req body in login { username: 'iopsert', password: 'vset' }
2. THIS IS WHAT WAS PASSED IN undefined
3. User found
4. /Users/John/practice-project/node_modules/mongodb/lib/utils.js:98
5. process.nextTick(function() { throw err; });
^
6. TypeError: Cannot read property 'password' of null
7. at /Users/John/practice-project/server/server.js:58:12
Строка 2 показывает, что req._id равен undefined
Ваше User found
заявление печатается до того, как вы проверите, есть ли ошибка или действительно ли пользователь существует, поэтому оно не является репрезентативным для фактического существования пользователя.
Строка 6 показывает, что выдается ошибка, потому что вы пытаетесь прочитать свойство password
из нулевого объекта.
Я бы рекомендовал изменить вашу логику входа, чтобы она выглядела примерно так:
//login endpoint
app.post('/api/login/', function(req, res) {
console.log('Performing login with req.body=');
console.log(JSON.stringify(req.body, null, 4));
// check for username
if (!req.body.username) {
return res.status(401).send({message: 'No username'});
}
// find user with username
db.collection('users').findOne({username: req.body.username}, function(err, user) {
// handle error
if(err) {
console.log('Error finding user.');
return res.status(500).send({message: 'Error finding user.'});
}
// check for user
if (!user) {
console.log('No user.');
return res.status(500).send({message: 'No user.'});
}
console.log('User found.');
// check password
if(user.password !== req.body.password) {
console.log('Wrong password.');
return res.status(401).send({message: 'Wrong password.'});
}
// return user info
return res.status(200).send(user);
});
Некоторые заключительные мысли:
- Обязательно обработайте ошибку (если она существует) и проверьте, что
user
она существует, прежде чем продолжить. - Всегда включайте
return
в своиreturn res.status(...).send(...)
инструкции, иначе последующий код будет выполнен. - Обычно не рекомендуется сохранять пароли в виде простых строк. Работайте над их шифрованием. Посмотрите на паспорт или bcrypt.
Надеюсь, это поможет.
Комментарии:
1. Извините, но на самом деле req._id просто не существует, потому что запрос не передал его, поэтому просто игнорируйте его. Ошибка tick также не возникает, если пользователь действительно существует в базе данных, поэтому я предполагаю, что, когда пользователь не найден, он неправильно обрабатывает ответ об ошибке? Кроме того, когда я делаю findOne() и вводит функцию, разве это уже не означает, что имя пользователя найдено? Зачем снова проверять пользователя и не должно ли этого быть
user.username
? Почему это означает by!user
, потому что у этого объекта нетusername
andpassword
? Спасибо за помощь2. Просто попробовал, но возврат ошибки фактически передается как a
response
из интерфейса и консоли, регистрирующей объект({message: "No user"})
, а не перехватывается вcatch()
функции какerror
. Могу ли я что-то упустить из интерфейса, чтобы уловить вcatch()
функции?3. Просто проверяю, видели ли вы мои последние комментарии. Пожалуйста, дайте мне знать.