У меня есть строка req.session.userId = user._id; в почтовом запросе с маршрутом /signin. Когда я помещаю console.info(req.session.userId) после этой строки, он возвращает идентификатор пользователя. Но req.session.userId возвращает undefined в почтовом запросе с маршрутом /notes. Как я могу получить идентификатор пользователя?
сеанс в MongoDB Compass действительно содержит userId:
{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"userId":"5b1634522951cc240c2fe55f"}
запрос на публикацию клиента / заметки
fetch('http://localhost:8000/notes', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(newNote)
})
.then(response => response.json())
.then(data => {
newNote._id = data._id;
const storedNotes = this.state.notes;
storedNotes.unshift(newNote);
this.setState({notes: storedNotes});
})
.catch(error => {
this.setState({error: 'Error adding note.'});
console.error('Error during adding note', error);
})
серверный запрос / заметки
app.post('/notes', (req, res) => {
if (!req.body.content) {
return res.status(400).send({
message: "Note content can not be empty"
});
}
console.info(req.session.userId);
const note = new Note({
title: req.body.title || "Untitled Note",
content: req.body.content,
});
note.save()
.then(data => res.send(data))
.catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating the Note."
});
});
};
server.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/trial')
.then(() => {
console.info("Successfully connected to the database");
}).catch(err => {
console.info('Could not connect to the database. Exiting now...');
process.exit();
});
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
secret: 'work hard',
resave: true,
saveUninitialized: false,
store: new MongoStore({
mongooseConnection: db
})
}));
app.use((req, res, next)=>{
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
if (req.method === "OPTIONS")
res.sendStatus(200);
else
next();
});
require('./routes/userRoutes')(app);
require('./routes/quoteRoutes')(app);
require('./routes/noteRoutes')(app);
app.listen(8000, function () {
console.info('Express app listening on port 8000');
});
Я попытался добавить учетные данные: «включить» в почтовый запрос клиента. По-прежнему возвращает undefined. Как это делается?





By default, fetch won't send or receive any cookies from the server, resulting in unauthenticated requests if the site relies on maintaining a user session (to send cookies, the credentials init option must be set).
А без файлов cookie ваш сервер не будет иметь доступа к данным сеанса.
Параметр учетных данных для fetch() может иметь три основных значения: omit, same-origin или include. Вам нужно будет установить одно из двух последних значений следующим образом:
fetch('http://localhost:8000/notes', {
method: 'POST',
credentials: 'include', // make sure session cookies are included
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(newNote)
})
Вам понадобится настройка credentials для ВСЕХ запросов fetch(), с которыми вы хотите отправлять файлы cookie, независимо от того, являются ли они GET, POST или любой другой командой.
Я добавил эту строку с одинаковым происхождением или включением, но она по-прежнему не работает. Что еще я могу сделать?
@lmathl - Каков URL-адрес веб-страницы (в строке URL-адреса браузера), с которой вы делаете этот fetch()?
@lmathl - Итак, сервер, код которого вы показываете, - это ваш сервер с портом 8000, который отличается от сервера с портом 3000, который загрузил веб-страницу? Как вы думаете, почему сервер с портом 8000 имеет тот же сеанс, что и сервер с портом 3000? Вы специально запрограммировали два сервера для совместного использования сеансов?
Я использовал app.use (session (...)) на своем сервере. Когда я вхожу в систему, создается userId. Так что должна быть сессия.
@lmathl - Могу ли я подтвердить, что вы используете два отдельных сервера node.js на одном и том же хосте, один находится на порту 3000, с которого поступает веб-страница, а другой - на порту 8000, который вы пытаетесь использовать для доступа к fetch() ? Почему вы используете два отдельных сервера node.js? Когда вы входите в систему и создаете сеанс входа в систему, на каком сервере вы это делаете?
Я использовал реакцию для создания представления в порту 3000. Экспресс-сервер для CRUD в порту 8000. Вышеупомянутый клиентский почтовый запрос выполняется в промежутке от 3000 до 8000.
Значит, было бы лучше сделать и то, и другое в одном порту?
@lmathl - это один хост, но ДВА сервера, один работает на порту 3000, а другой - на порту 8000. Я предполагаю, что вы что-то неправильно делаете в коде своих двух серверов, чтобы они могли совместно использовать сеансы между собой. credentials: 'include' позволит им обмениваться файлами cookie, но вам, возможно, придется сделать больше с материалами сеанса, чтобы убедиться, что они совместно используют фактические сеансы.
Когда я вхожу в систему, сеанс должен быть на 8000.
@lmathl - только один сервер решит эту проблему (вам все равно понадобится credentials: 'include' в fetch()), но все запросы легко увидят один и тот же объект сеанса. При правильном кодировании вы можете создать два отдельных серверных процесса, совместно использующих одни и те же объекты сеанса, но для этого требуется тщательное и явное кодирование.
@lmathl - Теперь ответ на ваш вопрос? Если да, вы можете сообщить об этом сообществу, щелкнув галочку слева от ответа. Если нет, сообщите нам, на что еще не ответили.
Я сделал запрос на редактирование вашего ответа, чтобы добавить строку "Сделайте то же самое с запросом на отправку входа". но это не принято. Я подумал, что мне просто нужно добавить учетные данные: 'include' для запросов, которые включают базу данных заметок, но на самом деле для запроса post входа также нужна эта строка. Если вы отредактируете свой ответ, я его приму.
@lmathl - вам нужен credentials: 'include' для запросов всеfetch(), с которыми вы хотите отправлять файлы cookie. Вот что объясняет мой ответ. Это не имеет ничего общего с GET или POST. Любой запрос ajax, с которым вы хотите отправлять файлы cookie. Вы тот, кто знает, для каких запросов вам нужны файлы cookie (не я), поэтому используйте их там, где это необходимо.
Можете показать почтовый индекс (клиент). Я думаю, вы не включаете «учетные данные» (файлы cookie).