Req.session.userId возвращает undefined в почтовом запросе

У меня есть строка 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');
});

Можете показать почтовый индекс (клиент). Я думаю, вы не включаете «учетные данные» (файлы cookie).

lipp 05.06.2018 13:09

Я попытался добавить учетные данные: «включить» в почтовый запрос клиента. По-прежнему возвращает undefined. Как это делается?

lmathl 05.06.2018 13:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
1 843
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из Страница MDN для fetch ():

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 05.06.2018 13:34

@lmathl - Каков URL-адрес веб-страницы (в строке URL-адреса браузера), с которой вы делаете этот fetch()?

jfriend00 05.06.2018 13:36

@lmathl - Итак, сервер, код которого вы показываете, - это ваш сервер с портом 8000, который отличается от сервера с портом 3000, который загрузил веб-страницу? Как вы думаете, почему сервер с портом 8000 имеет тот же сеанс, что и сервер с портом 3000? Вы специально запрограммировали два сервера для совместного использования сеансов?

jfriend00 05.06.2018 13:39

Я использовал app.use (session (...)) на своем сервере. Когда я вхожу в систему, создается userId. Так что должна быть сессия.

lmathl 05.06.2018 13:42

@lmathl - Могу ли я подтвердить, что вы используете два отдельных сервера node.js на одном и том же хосте, один находится на порту 3000, с которого поступает веб-страница, а другой - на порту 8000, который вы пытаетесь использовать для доступа к fetch() ? Почему вы используете два отдельных сервера node.js? Когда вы входите в систему и создаете сеанс входа в систему, на каком сервере вы это делаете?

jfriend00 05.06.2018 13:43

Я использовал реакцию для создания представления в порту 3000. Экспресс-сервер для CRUD в порту 8000. Вышеупомянутый клиентский почтовый запрос выполняется в промежутке от 3000 до 8000.

lmathl 05.06.2018 13:44

Значит, было бы лучше сделать и то, и другое в одном порту?

lmathl 05.06.2018 13:45

@lmathl - это один хост, но ДВА сервера, один работает на порту 3000, а другой - на порту 8000. Я предполагаю, что вы что-то неправильно делаете в коде своих двух серверов, чтобы они могли совместно использовать сеансы между собой. credentials: 'include' позволит им обмениваться файлами cookie, но вам, возможно, придется сделать больше с материалами сеанса, чтобы убедиться, что они совместно используют фактические сеансы.

jfriend00 05.06.2018 13:46

Когда я вхожу в систему, сеанс должен быть на 8000.

lmathl 05.06.2018 13:46

@lmathl - только один сервер решит эту проблему (вам все равно понадобится credentials: 'include' в fetch()), но все запросы легко увидят один и тот же объект сеанса. При правильном кодировании вы можете создать два отдельных серверных процесса, совместно использующих одни и те же объекты сеанса, но для этого требуется тщательное и явное кодирование.

jfriend00 05.06.2018 13:48

@lmathl - Теперь ответ на ваш вопрос? Если да, вы можете сообщить об этом сообществу, щелкнув галочку слева от ответа. Если нет, сообщите нам, на что еще не ответили.

jfriend00 07.06.2018 19:15

Я сделал запрос на редактирование вашего ответа, чтобы добавить строку "Сделайте то же самое с запросом на отправку входа". но это не принято. Я подумал, что мне просто нужно добавить учетные данные: 'include' для запросов, которые включают базу данных заметок, но на самом деле для запроса post входа также нужна эта строка. Если вы отредактируете свой ответ, я его приму.

lmathl 08.06.2018 06:10

@lmathl - вам нужен credentials: 'include' для запросов всеfetch(), с которыми вы хотите отправлять файлы cookie. Вот что объясняет мой ответ. Это не имеет ничего общего с GET или POST. Любой запрос ajax, с которым вы хотите отправлять файлы cookie. Вы тот, кто знает, для каких запросов вам нужны файлы cookie (не я), поэтому используйте их там, где это необходимо.

jfriend00 08.06.2018 07:25

Другие вопросы по теме