В настоящее время я работаю над приложением стека MERN, которое будет использовать форму входа / регистрации, связанную с моей базой данных Mongo. Мне удалось создать пользователя, хэшировать пароль пользователя, а затем сохранить этого пользователя в базе данных, а также войти в систему, проверив его учетные данные из базы данных.
Пытаясь использовать решение, являющееся отраслевым стандартом, я решил работать с Passport и Express-session, чтобы реализовать аутентификацию и сеансы для каждого пользователя при входе в систему. После того, как пользователь создан / вошел в систему, паспорт правильно сохраняет его информацию в req.user, и сеанс создается и регистрируется с помощью req.session. Ниже приводится консольный журнал req.user, за которым следует req.session:
user with id xxx serialized
email: ...
password: ...
isAuthenticated: true
Session {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true },
passport: {user: xxx } }
Все это отображается сразу после того, как я вхожу в систему, и, насколько мне известно, это означает, что сеанс был создан, и мой пользователь был правильно сериализован. Однако, когда я перехожу на новую страницу в веб-приложении, я теряю сеанс - req.user становится неопределенным, а req.sessionId изменяется каждый раз, когда страница делает это - что заставляет меня думать, что новый сеанс с пустым пользователем создается каждый раз. Я переключаю страницы (я использую метод fetch в моем NavBar в React, который срабатывает каждый раз, когда монтируется компонент). Google Chrome также неточно регистрирует файлы cookie, даже если они созданы, о чем свидетельствуют журналы консоли.
У меня вопрос: почему мой сеанс не сохраняется при переключении страниц? Моя цель - отслеживать данные сеанса, чтобы передать их моему интерфейсу React для рендеринга определенного контента. Есть ли лучший способ сделать это? Ниже мой заказ промежуточного программного обеспечения:
app.use(session({
secret: 'test',
saveUninitialized: false,
resave: true
}));
app.use(passport.initialize());
app.use(passport.session());
Вот методы, которые я вызываю в своем файле маршрутизатора:
router.get('/',function(req, res){
console.info(req.user);
console.info(req.session);
});
router.post('/login',passport.authenticate('local'), function(req,res)
{
console.info(req.user);
console.info(req.isAuthenticated());
console.info(req.session);
});
passport.serializeUser(function(user, done) {
console.info("user with id " + user._id + " serialized");
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
console.info("deserializing user with id " + id + " ");
User.findById(id, function(err, user) {
done(err, user);
});
});
Вот мой вызов api fetch из моего интерфейса:
componentDidMount(){
var current_user = "";
fetch("http://localhost:3001/users/", {
method: "get",
headers: {
'Accept':'application/json',
'Content-Type': 'application/json'
}
})
.then( (response)=> response.json())
.then( (response)=> {
if (response.user!==current_user){
current_user = response.user;
this.setState({
user: current_user
}), ()=> console.info(response);
}
})
}
Я также знаю, что в настоящее время метод выборки не будет работать должным образом: цель состоит в том, чтобы этот скелет работал должным образом и возвращал правильный идентификатор. Что неправильно регистрирует, так это сеанс и req.user еще до того, как я смогу даже получить возможность передать его своему интерфейсу. Любая помощь будет оценена по достоинству.
Спасибо за комментарий, но я не думаю, что отправка сообщения res.end () будет иметь какое-либо отношение к тому, что мой экспресс-сеанс не сохраняется после того, как я покину страницу. Я проверил его, результат тот же.
Если вы не вызываете «res.end», ответ, содержащий заголовок «set cookie», никогда не будет отправлен клиенту. Это на 100% необходимо, и вам всегда нужно вызывать res.end, res.send и т. д., Иначе соединение прервется. Странно, что это не помогло.
Да, к сожалению, безрезультатно. Хотелось бы, чтобы это сработало - я изменил метод get в маршруте '/' и '/ login', чтобы оба включали res.end () после журналов консоли. Может я неправильно делаю?





Вы не отправляете никаких ответов в своих маршрутах? Например, «router.post ('/ login')» должен вызывать «res.end ('success')» или что-то в этом роде. То, как это написано сейчас, приведет к тому, что клиент просто зависнет, так как вы никогда не ответите на запрос.