6

This problem has been driving me mad. I am using React with Apollo (GraphQL) on the frontend and authenticating using passport.js and express cookie-session on the backend. Everything works perfectly from any browser (haven't tested safari) on a desktop, however the cookie does not save on IOS and the user cannot login. This problem only happens using passport-local and if the browser does not already have a cookie. If I login using passport-google or passport-facebook it works, then if I logout and use passport-local again, it works, even if it's a different user. Also, it works the first time around if I go to my settings and turn off "Prevent Cross-Site Tracking" for IOS Safari, however I can't turn that off if I want to use this as a PWA.

My express setup looks like this (leaving out all the imports):

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
  })
);

My login route:

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);
});

In React I am sending the request using 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);
        }
      });

Another, maybe related, issue is that if I add {secure: true} option to cookie-session it doesn't work at all, even though I am using a valid SSL cert through AWS where the frontend is hosted in an S3 bucket. The backend is on heroku and also is https. The site is live if it helps for anyone to check it out and try using it and inspecting the dev tools. I haven't tested it on android or ipad yet. https://toomanylists.com

Anyway, I suppose this is a long shot but I am hoping maybe there is something easy I am missing and it is not an unsolvable IOS issue with my setup and them preventing cookies (is this new in IOS 12?). Also, does anyone know if this would also be an issue using JWT's and if that is a secure way to authenticate users?

  • Just stumbled upon a similar issue. iOS 12.1 and `express-session` do not work together properly. Session is being initialized however additional values are not being stored. – scarably Nov 14 '18 at 23:13
  • 3
    I am having an issue with this too. On PC and android, everything thing works perfect.... on IOS(IPAD) the sessions get created for every request made instead of using existing session. Also properties stored on session dont apear in the store. Did you guys figure this out? – Firecore Jan 18 '19 at 01:56
  • 1
    any solutions yet? Works on Safari on the PC, but not on the Iphone's safari...... – ezg Sep 03 '20 at 02:19
  • 1
    Not sure if there is a solution yet, I haven't been working in Node in over a year now – Michael Aaron Wilson Nov 19 '20 at 15:45
  • Pls how did you solve this issue? Any solution yet? – Paulliano Jul 19 '22 at 11:45
  • Any updates here? – AndrewLeonardi Sep 02 '22 at 14:01
  • 1
    I am still unable to solve this issue. I have no idea why this is happening. Do you find any solution yet? @AndrewLeonardi – Paulliano Sep 30 '22 at 11:43
  • 1
    @Paulliano Yes for sure. Check this post here https://stackoverflow.com/questions/59384430/cookies-only-set-in-chrome-not-set-in-safari-mobile-chrome-or-mobile-safari – AndrewLeonardi Sep 30 '22 at 13:20
  • Thank you so much, I would try it out. @AndrewLeonardi – Paulliano Sep 30 '22 at 13:56

0 Answers0