Метод 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);
}