The curious case of failed logins
tl;dr The fetch credentials default changed in Chrome/68 and matters for same origin requests.
We recently launched our new portal, allowing users to login and view their wealth. The login flow is fairly standard; a user enters their email and password and the app sends them to the server which if valid replies setting a cookie with a session token. We tested this in Chrome, Firefox, and Safari, and it worked, so we shipped.
Then we started to recieve reports from frustrated users, they couldn’t login. They said they entered their login details and instead of reaching the home page their login details just cleared. They would send screenshots of empty login pages and we’d scratch our heads — we could always login.
Fortunately we had logs we could check, and we noticed these login failures were associated with browsers we hadn’t checked ...SamsungBrowser/9.2 Chrome/67.0.3396.87...
, ...Silk/66.2.10 like Chrome/66.0.3359.126...
and others. It turns out that Samsung’s browser has 4% of the uk market, slighlty more than Firefox, so we focused on Samsung. Fortunately we own a Samsung phone and could confirm what our users were seeing.
Testing in the Samsung browser demonstrated that the login would succeed, but no session cookie would be set. We first assumed Samsung was incorrectly identifying our cookie as third party and blocking it, but nothing we tried or read supported this. Then we came across this stack overflow question, which resonated as our login was an ajax request, using the fetch api,
await fetch(
"/v0/login/",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({ email, password }),
method: "POST",
)
The answer suggested was to add credentials: "same-origin"
to the fetch in order to allow cookies to be sent and cruically received. Yet this is the default value, as confirmed in MDN. It also seemed to be unrelated as the credentials property is always documented in terms of cross-origin requests, whereas our login was to the same site.
After a frustrated while reading and searching about whether the fetch credentials affected same origin requests, we found that in Chrome 68 the default was changed from omit
to same-origin
. From this it is clear what the issue was, our users were using the latest Samsung browser yet that browser was built on an outdated chromium (Chrome 67) that had the default set to omit
. Adding credentials: "same-origin"
to the fetch fixed the problem.
In conclusion
This was a tricky isolated bug to track down and fix, especially as some of the documentation on fetch credentials suggests that they only apply to cross-origin requests. Hopefully as you are reading this we’ve saved you from a few hours of confusion.