All of the sudden, with no changes on my side, Google sign in is broken on Safari 13.0.4 running on macOS 10.15.2.
I started getting reports from users in recent days and am able to reproduce it myself. The popup appears with the consent form/account chooser, you proceed, see a spinner for a second that says "one moment please" then the popup disappears, and none of the callbacks fire. There are no errors logged to the console that I can see when this happens. It works fine on Safari on iOS, macOS Chrome, etc.
Did something change recently?
I'm experiencing the same and wondering if it's due to Safari updates and new cookie policies:
https://webkit.org/blog/9521/intelligent-tracking-prevention-2-3/. However, I can't get their ITP Debug tool to work :/.
For me even if I interact with accounts.google.com, e.g. by signing out, and then go back through the flow, it's still broken. In the past with ITP issues, interacting with the domain prevented the issue.
Despite this being the official client, I have to believe that high volume sites are using something else so they aren't randomly stuck with users who can't log in.
@razor-1 are you running your code on a CMS or platform? I'm using Sharepoint and wondering if that's contributing to the issue.
No. This is a site I control top to bottom.
Anyone managed to find a workaround/fix yet?
We have multiple apps that use the client side sign in flow with this library.
I guess one workaround would be to not use this library and use the server side sign in flow (https://developers.google.com/identity/protocols/OAuth2WebServer)
Can you provide steps to reproduce the issue from scratch, i.e. on a fresh webpage?
The sample in https://developers.google.com/identity/sign-in/web/sign-in doesn't work for me in Safari, but if I create a simple webpage based on the guide, it does work in Safari:
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id" content="REPLACEME.apps.googleusercontent.com">
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
}
</script>
@eesheesh which version of Mac OS X are you running?
Our customers started noticing this issue after upgrading OS X to v10.15.2 from v10.15.1.
I'll create a small reproducible sample tomorrow when i get to the office.
I'm on macOS 10.15.2 with Safari 13.0.4. I'll wait for your sample, thanks!
I was able to fix the issue by making sure that Preferences->Privacy "Prevent cross-site tracking" was _checked_. Never thought to try this because it seemed so counterintuitive, quite the Safari 馃悰 .
A couple of other conversations around the same issue:
https://discussions.apple.com/thread/250938524
https://www.reddit.com/r/Safari/comments/eaaanh/safari_1304_on_macos_changes_to_prevent_crosssite/
@matt-mcdaniel Thanks. Though it doesn't seem to make it work in Private Window browsing even with "Prevent cross-site tracking" enabled.
@eesheesh as matt said the bug also seems to be dependent on having "Prevent cross-site tracking" disabled in Safari privacy preferences. Though it seems that if you try to sign in to a website using this javascript client library in a Private Window it doesn't work regardless of that setting.
Our main issue with this bug is that we use Safe Exam Browser for locking down student devices in exam environments and Safe Exam Browser uses Safari to display websites. Sadly the "Prevent cross-site tracking" Safari preference doesn't fix the issue in Safe Exam Browser.
I can confirm that enabling "Prevent cross-site tracking" fixes this. Is anyone who owns this repo looking at fixing it, or should we just abandon this client?
I tried this on my sample above, and it works regardless of whether "Prevent cross-site tracking" is enabled or not (I deleted cookies for my webserver's domain between tests).
If someone can add an example page that can reproduce the issue, I'll try this on my system as well.
@danielx yes a private window fails for me regardless.
@eesheesh you are on 13.0.4 right? Can you try unchecking "prevent cross-site tracking", clearing data, quitting safari and reopening and trying again? Multiple people on my team have been able to reproduce the issue.
@razor-1 this seems to be an issue with Safari rather than this repo, I know that there are open tickets with Apple for this issue. Doesn't seem to be specific to google apis.
@matt-mcdaniel do you have any links to these open tickets?
I looked at the webkit issue tracker but i couldn't find a ticket that i thought was created for this issue since i'm not sure what the root cause is.
Thanks @matt-mcdaniel - I can now reproduce this after following your steps (using the same test webpage I've used before).
I looked around a bit more and it seems like there are some known issues with this feature of Safari on 13.0.4, for example: https://discussions.apple.com/thread/250942525.
Based on that, I think it's best to wait for Apple to issue a fix. I can't reproduce the issue on Safari Technology Preview Release 98 (Safari 13.1, WebKit 15609.1.13.4), so I assume this is going to be fixed in Safari soon.
I too am having the same issues with Safari. To confirm it wasn't my code, I copied the sample auth html page and replaced with my credentials with no success. I will disable Google features on my web application for Safari browsers until it is resolved.
google-api-javascript-client/samples/authSample.html
I can confirm that this bug exists in Safari 13.0.3. 馃槬
However, it doesn't exist in Safari 11.1.1 馃帀
Same here, Safari V. 13.4.5.
Means I have to change the entire way I authenticate. Thanks apple.
If you have "access_token" for example after using another Google Sign in method you can use Google API CORS to access Google API authenticated requests
function asyncXhr(method, url) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function() {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject(JSON.parse(xhr.response));
}
};
xhr.onerror = function() {
reject(JSON.parse(xhr.response));
};
xhr.send();
});
}
await asyncXhr(
'GET',
`https://www.googleapis.com/gmail/v1/users/${email}/threads/${threadId}?access_token=${encodeURIComponent(accessToken)}`
);
Same here, Safari V. 13.4.5.
Means I have to change the entire way I authenticate. Thanks apple.
Unfortunately I have to do the same :(
@yuzhakovvv, please note that adding access_token to your query string will be deprecated in 2021. I'd suggest using setRequestHeader() on the XHR and add the token to the Authorization header, like this:
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
a workaround that I find out is to use //apis.google.com/js/platform.js instead of the lightweight SDK //apis.google.com/js/api.js
I have to do a check for Safari browser and load this script instead
Similar issue on Chrome IOS.
When 'Allow Cross-Site Tracking' setting is turned off, the sign-in page shows 'One moment please', immediately returns and does not send the callback.
Sign in does work when 'Allow Cross-Site Tracking' is turned on.
@thientran1707 I was also using api.jsand have tried switching to platform.js but no luck.
I cannot reproduce the issue in Mac OS Chrome & Safari or iOS Safari. Another strange observation is that it does work for initial login (after clearing browsing data).
Here is a sample of what I am doing (simplified a bit for ease of understanding)
// On page load
window.gapi.load("client:auth2", async () => {
await window.gapi.client.init({
clientId: "XXXXXXXXX",
scope: "email",
});
auth = window.gapi.auth2.getAuthInstance();
});
// On sign in click
if (auth.current.isSignedIn.get()) {
await auth.current.signOut(); // I force sign in at the moment.
}
await auth.signIn();
const tokenId = auth.currentUser.get().getAuthResponse().id_token;
// ... pass id token to server for validation and app sign in
It's not working on 13.x.x.
But it's worked before Big Sur macOS release.
After i updated Big Sur and Safari 14.x.x ... it work again.
Do we have an idea to fix that?
Most helpful comment
@yuzhakovvv, please note that adding
access_tokento your query string will be deprecated in 2021. I'd suggest usingsetRequestHeader()on the XHR and add the token to theAuthorizationheader, like this: