Метод deserializeUser() в Passport-local не вызывается во время развертывания. Отлично работает в разработке

(Да, я знаю, что компоненты класса устарели, обновляются до функциональных/хуков после успешного развертывания)

Я реализовал приложение MERN (MongoDB, Express, React и Node.js) с аутентификацией, используя локальную стратегию Passport и ES6.

Ожидается: когда пользователь входит в систему, он отправляет запрос на маршрут «/auth/login», который аутентифицируется с использованиемpassport.authenticate()метод. Если аутентификация прошла успешно, сервер отправляет ответ «успех» обратно клиенту.

Как только клиент получает ответ «успех», вызывается метод компонента App.js. В этом методе клиент отправляет запрос"/auth/test"маршрут, чтобы проверить, аутентифицирован ли пользователь с помощью .

Если пользователь аутентифицирован, сервер отправляет обратно объект пользователя, который затем преобразуется в строку и сохраняется в локальном хранилище клиента, чтобы указать, что пользователь вошел в систему.

Режим разработки: для разработки у меня есть клиент на одном порту и API на другом. Все работает нормально .

В настоящее время: после развертывания я размещаю клиент и API через Render.com.

  • Я убедился, что все переменные среды правильно установлены в Render.
  • я обновил любойbaseURLчтобы соответствовать новому клиенту и URL-адресам API соответственно, когда я отхожу от localhost.
  • Я поместил console.log везде, чтобы обеспечить ожидаемый поток (это не так. См. Ниже).

Текущий поток:

  • serializeUser()вызывается с правильным идентификатором.
  • localStrategyвызывается, и он находит правильного пользователя и пароль и возвращаетdone(null, userObj).
  • возвращает ожидаемый статус.
  • срабатывает в App.js.
  • componentDidMount()) срабатывает и здесь мы проверяемreq.isAuthenticated.

Примечания к CORS:

  • Я не получаю никаких ошибок/предупреждений о CORS
  • Я выбираю от клиента сcredentials: "include"
  • Я выбираю с сервера с помощью
            const allowedOrigins =
      process.env.NODE_ENV === "development"
        ? "http://localhost:3000"
        : "https://my-client.onrender.com";
    const corsOptions = {
      origin: allowedOrigins,
      credentials: true,
    };
    app.use(cors(corsOptions));
    

Проблема: req.isAuthenticated()возвращаетсяfalseпотому чтоreqне определено.

Что я видел (через журналы консоли):

  • deserializeUser()никогда не вызывается (вызывается нормально в dev)
  • Файлы cookie никогда не устанавливаются во время развертывания (файлы cookie устанавливаются нормально в dev)
  • В журналах API нет ошибок
  • у меня в консоли ошибок нет

Спасибо

Клиент

          const url = baseURL + "/auth/login?username=" + id + "&password=" + pw;
    const res = await fetch(url, {
      method: "POST",
      credentials: "include",
    });

           fetch(baseURL + "/auth/test", {
        credentials: "include",
      })

API

/auth/loginМаршрут

      authRoute.post("/auth/login",passport.authenticate("local"),
  (req, res) => {
    res.status(200).send("Login successful");
  },

/auth/testМаршрут

      authRoute.get("/auth/test", (req, res) => {
  const isAuth = req.isAuthenticated(); // PROBLEM: Returns false because req is undefined
// etc.

паспортконфигурация

        app
    .use(
      session({
        secret: process.env.SESSION_SECRET,
        resave: false,
        saveUninitialized: true,
        cookie: {
          secure: process.env.NODE_ENV === "development" ? false : true,
          httpOnly: process.env.NODE_ENV === "development" ? false : true,
          sameSite: process.env.NODE_ENV === "development" ? "" : "none", // Set if using CORS
          domain: process.env.NODE_ENV === "development" ? "" : ".onrender.com",
          path: "/",
          maxAge: 1000 * 60 * 5,
        }, // 5 minutes
      })
    )

    .use(passport.initialize())
    .use(passport.session());

Заранее спасибо!

1 ответ

Одна вещь, которая выглядит подозрительно в вашей конфигурации, это эта строка, в частности.предшествующий вашему домену:

domain: process.env.NODE_ENV === "development" ? "" : ".onrender.com",линия.

Я бы вообще отказался от этой строки. Вы также можете изменить его на простоonrender.com.

Express также не установит cookie, если удаленный сервер передает запрос через посредника, отличного от http. Вы можете сказать ему доверять этому прокси:

      if (process.env.NODE_ENV === 'production') {
  app.set('trust proxy', 1);
}
Другие вопросы по тегам