Эта проблема сводила меня с ума. Я использую React с Apollo (GraphQL) на внешнем интерфейсе и проверяю подлинность с использованием passport.js и выражаю cookie-session
на внутреннем интерфейсе. Все отлично работает из любого браузера (не тестировал сафари) на рабочем столе, однако cookie не сохраняется на IOS и пользователь не может войти в систему. Эта проблема возникает только при использовании passport-local
и если в браузере еще нет файла cookie. Если я войду в систему с помощью passport-google
или passport-facebook
, это сработает, тогда, если я выйду из системы и снова использую passport-local
, это сработает, даже если это другой пользователь. Кроме того, это работает в первый раз, если я перехожу к своим настройкам и отключаю «Предотвращение межсайтового отслеживания» для IOS Safari, однако я не могу отключить это, если хочу использовать это как PWA.
Моя экспресс-настройка выглядит следующим образом (без импорта):
app.use(
cookieSession({
maxAge: 24 * 60 * 60 * 1000 * 30,
keys: [process.env.COOKIE_KEY],
overwrite: true
})
);
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
const whitelist = [
"https://toomanylists.com",
"https://www.toomanylists.com"
];
app.use(
cors({
origin: (origin, callback) => {
console.log(origin);
if (whitelist.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error("blocked by CORS"));
}
},
credentials: true
})
);
app.options("*", cors());
app.use("/auth", authRoutes);
mongoose.connect(process.env.MONGODB_URI);
mongoose.connection.once("open", () => {
console.log("Connected to Database");
});
const authCheck = (req, res, next) => {
if (!req.user) {
res.redirect("https://toomanylists.com");
} else {
next();
}
};
app.use(
"/graphql",
authCheck,
graphqlHTTP({
schema: schema,
graphiql: true
})
);
Мой логин маршрут:
router.post("/login", jsonParser, (req, res, next) => {
passport.authenticate("user-login", (err, user, info) => {
if (err) {
return next(err);
}
if (!user) {
return res.status(401).send(JSON.stringify(info));
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.status(200).send(JSON.stringify(info));
});
})(req, res, next);
});
В React я отправляю запрос с использованием API извлечения:
fetch(<my_server_url/login>, {
method: "POST",
credentials: "include",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(this.state)
}).then(response => {
//if fails alerts with custom message
if (response.status === 401) {
response.json().then(json => {
alert(json.message);
});
} //if successful refresh with cookies
if (response.status === 200) {
window.location.reload(false);
}
});
Другая, возможно связанная с этим проблема заключается в том, что, если я добавлю опцию {secure: true}
к cookie-session
, она вообще не будет работать, даже если я использую действующий сертификат SSL через AWS, где внешний интерфейс размещается в корзине S3. , Бэкэнд находится на героку и также является https. Сайт работает, если кто-то поможет проверить его и попробовать использовать его и осмотреть инструменты разработки. Я еще не тестировал его на Android или Ipad. https://toomanylists.com
В любом случае, я полагаю, что это длинный путь, но я надеюсь, что, может быть, есть что-то простое, что я упускаю, и это не является неразрешимой проблемой IOS с моей настройкой и предотвращением использования файлов cookie (это новое в IOS 12?). Кроме того, кто-нибудь знает, будет ли это также проблемой с использованием JWT и является ли это безопасным способом аутентификации пользователей?