这个问题使我发疯。我在前端使用带有Apollo(GraphQL)的React,并使用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);
}
});
另一个可能相关的问题是,即使我在托管前端的AWS上使用有效的SSL证书,如果我将{secure: true}
选项添加到cookie-session
,它也根本不起作用在S3存储桶中后端在heroku上,也是https。如果该站点可帮助任何人签出并尝试使用它并检查开发工具,则该站点已启用。我尚未在android或ipad上对其进行测试。 https://toomanylists.com
无论如何,我想这是一个远景,但是我希望也许我缺少一些容易的东西,这不是我的设置无法解决的IOS问题,并且它们可以防止Cookie(这是IOS 12中的新功能吗?)。另外,有人知道使用JWT是否也会成为问题,并且这是否是验证用户身份的安全方法?