I have a MERN app where the backed and frontend are deployed separately. I have CORS configured properly and state management with RTK Query. I'm using an auth token with a refresh token rotation. When the user logs in, they can check the "Trust this device" box and a "persist" flag is set in localstorage. In theory, if the user refreshes (which I know is unlikely in an SPA), the app pulls the auth token if there is one and if not, uses the refresh token to get a new auth token. If validated, they stay logged in. This works perfectly for Edge, Chrome, and Firefox desktop browsers. But for some reason, it's not working on mobile browsers.
I have an iPhone, but no Mac so I can't do remote logging. I found that it works for Safari, but that's it. After some toying, I found in Chrome that if I turned on 'Allow Cross-website Tracking', it suddenly worked. I cannot figure out why or how I set up my process correctly to not require that because I can't assume my users will know to do that. I have made sure that my origins are listed in my CORS and I know it's working because of the desktop browsers not giving errors.
Here's my CORS setup
app.use(cors(corsOptions))
import allowedOrigins from './allowedOrigins.js'
const corsOptions = {
origin: (origin, callback) => {
if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
},
credentials: true,
optionsSuccessStatus: 200,
}
export default corsOptions
Here's my cookies
// Create secure cookie with RefreshToken
res.cookie('jwt', refreshToken, {
httpOnly: true, //accessible only by web server
secure: true, //https
sameSite: 'None', //cross-site cookie
maxAge: 30 * 24 * 60 * 60 * 1000, //cookie expiry: set to match rT
})
I understand my cookies are set to SameSite none which makes them inherently a cross-site cookie, but how do I avoid that if the server is deployed separately from the frontend?
For anyone else having this trouble, after much reading I was able to fix it. Turns out that if you host your backend and frontend separately on a site that's registered in the Public Suffix List, any subdomains are seen as cross-site. The only way to fix this is to register your own domain name and add a subdomain for the server.
I used Google Domains as they're cheap and extremely easy to setup, but this fixed my problem.