3

I can't seem to set the cookies if I make the api call from Netlify, but with Postman it works.

I don't understand why.

My code looks like this:

router.post('/login', localAuth, async (req, res) => {
    // The code goes through and returns status 200
    return res.status(200)
    .cookie('accessToken', accessToken, {
        signed: true,
        httpOnly: true,
        secure: true,
        maxAge: 15 * 60 * 1000,
        sameSite: 'none', // <-- I also tried lax
    }).cookie('refreshToken', refreshToken, {
        signed: true,
        httpOnly: true,
        secure: true,
        maxAge: 7 * 24 * 60 * 60 * 1000,
        sameSite: 'none', // <-- I also tried lax
   }).send( // something );
});

Then the code tries a different route right after which fails due to missing cookies

router.get('/user', accessjwtAuth <-- this fails due to no cookies, async (req, res) => {})

Netlify comes with SSL certificate by default. The call from the frontend looks like this:

const config = {
    baseURL: `${API_URL}/api/auth/login`,
    method: 'post',
    withCredentials: true,
    headers: {'Content-Type': 'application/json',},
    data: values,
};
axios(config).then((res) => {});

Lastly, the express app is configured like this:

const allowed_origins = ["https://something.netlify.app", "localhost:8080"];
app.use(function(req, res, next) {
    const origin = req.headers.origin;
    if (allowed_origins.indexOf(origin) > -1) {
        res.setHeader('Access-Control-Allow-Origin', origin);
    };
    res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    res.header("Access-Control-Allow-Credentials", "true");
    next();
});

I keep getting this for my signedcookies, [Object: null prototype] {}

I noticed that this issue happens on Safari and not Chrome. In Chrome, the req has both accessToken & refreshToken. I also noticed that if I set sameSite: 'lax' then only the refreshToken gets preserved.

Joseph K.
  • 1,055
  • 3
  • 23
  • 46
  • https://www.theverge.com/2020/3/24/21192830/apple-safari-intelligent-tracking-privacy-full-third-party-cookie-blocking Maybe you could try to enable "Cross-site tracking" in Safari to see if the problem relies on it. – dongnhan Aug 15 '20 at 14:52
  • That actually worked. Safari and Chrome both logged in and retained their tokens for the next api call. I can't expect users to change that setting though, so where do I go from here to fix? Finally something that worked, thanks. – Joseph K. Aug 15 '20 at 15:02

1 Answers1

5

From MDN

Browsers are migrating to have cookies default to SameSite=Lax. If a cookie is needed to be sent cross-origin, opt out of the SameSite restriction by using the None directive. The None directive requires that the Secure attribute also be used.

You are doing the correctly with Chrome (by setting sameSite=None and secure=true)

For the Safari with its major update to Safari Intelligent Tracking Prevention (ITP), I think we have to manually enable the Cross-site tracking preference. I think you could tell your users to do it or try to think of another way to implement the feature without cross-site cookie.

dongnhan
  • 1,698
  • 9
  • 12