IOS 不从快速 cookie 会话保存 cookie

问题描述 投票:0回答:1

这个问题一直让我抓狂。我在前端使用 React 和 Apollo (GraphQL),并在后端使用 Passport.js 和 Express

cookie-session
进行身份验证。在桌面上的任何浏览器(尚未测试 safari)上,一切都可以完美运行,但是 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 中,我使用 fetch 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
,它根本不起作用,即使我通过 AWS 使用有效的 SSL 证书,其中前端托管在 S3 存储桶中。后端是heroku,也是https。如果该网站可以帮助任何人查看并尝试使用它并检查开发工具,则该网站已上线。我还没有在 Android 或 ipad 上测试过。 https://toomanylists.com

无论如何,我认为这是一个不太可能的事情,但我希望也许有一些我遗漏的简单的东西,并且这不是我的设置和它们阻止cookie的无法解决的IOS问题(这是IOS 12中的新功能吗?)。另外,有谁知道这是否也是使用 JWT 的问题以及这是否是验证用户身份的安全方法?

ios express https passport.js session-cookies
1个回答
0
投票

可能有一千种解决方案,但这是我的。

我需要在开发中使用 CORS,但在生产中不需要。下面的两组代码都是 CORS 所需要的(我认为),但我只检查了第一组代码以查看我的环境变量

use_cors
是否为真。一旦我通过在它们周围放置 if 语句来删除生产中与 CORS 相关的标头(该变量在产品中设置为 false),问题就解决了。

长话短说:无论您是否使用 CORS,请确保您的标头正确。

//Set up CORS in development, but not in production
if (process.env.USE_CORS === 'true') {
  app.use(
    cors({
      origin: process.env.CLIENT,
      methods: ['GET', 'POST', 'PUT'],
      credentials: true
    })
  )
}

//Set CORS Headers in development, but not in production
if (process.env.SET_CORS_HEADERS === 'true') {
  app.use(function (req, res, next) {
    res.header('Access-Control-Allow-Credentials', true)
    res.header('Access-Control-Allow-Origin', req.headers.origin)
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
    res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept')
    next()
  })
}
© www.soinside.com 2019 - 2024. All rights reserved.