Passport js Как сохранить пользователя в сеансе?

Я хочу иметь доступ к моему пользователю в req.user, который должен храниться в сеансе. Вот мой серверный js-код

const express = require("express");
const bodyParser = require("body-parser");
const socketIO = require("socket.io");

const http = require("http");
const app = express();
const server = http.createServer(app);
const io = socketIO(server);

const router = require("express-promise-router")();
const cors = require("cors");
const cookieParser = require("cookie-parser");
const validator = require("express-validator");
const session = require("express-session");
const MongoStore = require("connect-mongo")(session);
const mongoose = require("mongoose");
const passport = require("passport");
const keys = require("./config/keys");

//import cloudinary
require("./services/cloudinaryUpload");
mongoose.connect(
  "mongodb://localhost/chat-app",
  { useNewUrlParser: true },
  () => console.info("Connected to Mongo Server")
);

app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

//require the models
require("./models/users.js");
require("./models/groups.js");


//require passport
require("./services/passport");
app.use(
  session({
    secret: "thisisasecretkey",
    resave: true,
    saveInitialized: true,
    saveUninitialized: true,
    store: new MongoStore({ mongooseConnection: mongoose.connection })
  })
);
app.use(passport.initialize());
app.use(passport.session());

app.use(router);

//Require sockets
require("./sockets/groupchat")(io);

app.set("trust proxy", 1);

//Require routes
require("./routes/users")(router);
require("./routes/admin")(router);
require("./routes/home")(router);
require("./routes/group")(router);

app.use(express.static("public"));

app.use(validator());

server.listen(5000, () => {
  console.info("Server is listening on the port 5000");
});

Вот мой js-код паспорта:

const passport = require("passport");
const mongoose = require("mongoose");
const User = mongoose.model("users");
const LocalStrategy = require("passport-local").Strategy;
const FacebookStrategy = require("passport-facebook").Strategy;
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const keys = require("../config/keys");

passport.serializeUser((user, done) => {
  done(null, user.id);
});

passport.deserializeUser(async (id, done) => {
  try {
    const user = await User.findById(id);
    console.info("passport has deserialized the user", user);
    done(null, user);
  } catch (error) {
    done(error, null);
  }
});


passport.use(
  new FacebookStrategy(
    {
      clientID: keys.facebook.clientID,
      clientSecret: keys.facebook.clientSecret,
      profileFields: ["email", "displayName", "photos"],
      callbackURL: "/api/auth/facebook/callback",
      passReqToCallback: true,
      proxy: true
    },
    async (req, token, refreshToken, profile, done) => {
      try {
        const user = await User.findOne({ facebook: profile.id });
        if (user) {
          return done(null, user);
        }
        const newUser = new User();
        newUser.facebook = profile.id;
        newUser.fullname = profile.displayName;
        newUser.email = profile._json.email;
        newUser.userImage = `https://graph.facebook.com/${
          profile.id
        }/picture?type=large`;
        newUser.fbTokens.push({ token });
        const savedUser = await newUser.save();
        done(null, savedUser);
      } catch (err) {
        return done(err, false);
      }
    }
  )
);

passport.use(
  new GoogleStrategy(
    {
      clientID: keys.google.clientID,
      clientSecret: keys.google.clientSecret,
      profileFields: ["email", "displayName", "photos"],
      callbackURL: "/api/auth/google/callback",
      passReqToCallback: true,
      proxy: true
    },
    async (req, accessToken, refreshToken, profile, done) => {
      try {
        const user = await User.findOne({ google: profile.id });
        if (user) {
          return done(null, user);
        }
        const newUser = new User();
        newUser.google = profile.id;
        newUser.fullname = profile.displayName;
        newUser.email = profile.emails[0].value;
        newUser.userImage = profile._json.image.url;
        const savedUser = await newUser.save();
        done(null, savedUser);
      } catch (err) {
        return done(err, false);
      }
    }
  )
);
module.exports = passport;

У меня есть маршрут получения пользователя, и я хочу отправить пользователя, но он не работает:

  router.get("/api/get-user", (req, res) => {
    if (req.user) {
      return res.status(200).send(req.user);
    }
    return res.status(401).send({ message: "The user does not exist" });
  });

deserializeUser вызывается? Если да, то каков его результат? Кроме того, вы дважды вызываете passport.initialize(), и похоже, что вы устанавливаете cookieParser и validator слишком поздно.

robertklep 27.10.2018 14:02

@robertklep deserializeUser вызывается один раз только во время аутентификации. У него есть полный пользователь. Я обновил код, который все еще не работает.

Unity Hour 27.10.2018 14:07

@robertklep Можете сказать мне, почему это происходит?

Unity Hour 27.10.2018 14:21

@robertklep нужно ли вызывать deserializeUser при каждом запросе?

Unity Hour 27.10.2018 15:05

Да, deserializeUser должен вызываться при каждом запросе (после входа пользователя в систему). Если он не вызывается, это может означать, что срок действия cookie сеанса истек или обработчик маршрута (для /api/get-user) не смонтирован в правильном месте (слишком рано, до промежуточного программного обеспечения сеанса и Passport).

robertklep 27.10.2018 15:11

@robertklep вызывается только тогда, когда я нажимаю на вход через Google. (до того, как мне покажут страницу регистрации)

Unity Hour 27.10.2018 15:23

В этом случае начните проверять каждый шаг процесса: вызывается ли обработанная стратегия Google, находит ли она существующего пользователя или создает ли нового, вызывается ли serializeUser (который сериализует пользовательские данные, чтобы их можно было использовать в сеанс), сохраняются ли данные сеанса в MongoDB, устанавливается ли файл cookie сеанса? И т.п.

robertklep 27.10.2018 15:26

@robertklep При дополнительном анализе я обнаружил, что он вызывается только на тех маршрутах, которые имеют промежуточное ПО паспорта. Но для других маршрутов он не работает. В маршруте с промежуточным программным обеспечением Passport.authenticate у него есть полная информация о пользователе.

Unity Hour 27.10.2018 15:26

Позвольте нам продолжить обсуждение в чате.

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

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