Google-api-javascript-client: gapi auth2 issue on safari

Created on 1 Feb 2019  Â·  18Comments  Â·  Source: google/google-api-javascript-client

I am creating ann app which has to be connected to Google API. This is my code to call a function when user is signed in gapi.auth2.getAuthInstance().isSignedIn.listen(function(){googleConnected();});
My app works perfectly on chrome and on safari private browser, but on safari usual browser not working. The googleConnected() function isn't called. Sorry for my english

Most helpful comment

Any update? Same case on my end.

All 18 comments

???????

does anyone knows why? removing the cache will resolve the issue but we hope the issue can be resolve via javascript as a solution if possible. this seems to happen after a period of time on the safari browser.

Apparently we are experiencing the same issue.

We had several users for who the OAuth process fails (we tried both the gapi.signin2.render(...) as well as gapi.auth2.getAuthInstance().signIn()). We are using the onsuccess and onfailure handlers, and for these users neither of them was called at the end of the sign in process. No report on the console, no failed request.

It also happened to one of our colleagues and it kept failing on Safari (the browser he uses most of the time), whereas on Safari incognito and Chrome it worked. Once we deleted all cookies on that Safari, it started working.

I have no idea how to even start debugging this. Any tips? Or can anyone direct me where to post this report?

I'm having exactly the same problem, this always return true in Chrome, Opera, Firefox, Edge and Safari Private Window:

gapi.auth2.getAuthInstance().signIn()

But in Safari Normal window it returns false... doesn't make sense!

@shahazaryan I had the same problem as you, I was able to solve simply by going to preferences > security in Safari and click on Block All cookies, this will give you an alert saying it will also delete all cookies, and after enabling cookies again, the API start working beautifully!

Same issue here. Our users are unable to sign in using Safari (unless it's incognito).

Same issue here. Our users are unable to sign in using Safari (unless it's incognito).

Can you try deleting the cookies of the normal window and try again, that fixed the problem for me and I want to know if the root cause is a cached cookie from google, that, of course, is not present in private window.

I have written a note for my users to use another browser or safari private
mode.

On Thu, Aug 8, 2019 at 8:37 AM Carlos Amílcar Sánchez Rosa <
[email protected]> wrote:

Same issue here. Our users are unable to sign in using Safari (unless it's
incognito).

Can you try deleting the cookies of the normal window and try again, that
fixed the problem for me and I want to know if the root cause is a cached
cookie from google, that, of course, is not present in private window.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/google/google-api-javascript-client/issues/503?email_source=notifications&email_token=AJTXGWXQGIXJHLYL6A57WM3QDOPGZA5CNFSM4GTZNR6KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD32MZ2I#issuecomment-519359721,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AJTXGWW2J3VIGOZ7E3O75TDQDOPGZANCNFSM4GTZNR6A
.

Any update? Same case on my end.

look what I've found here

Safari with Intelligent Tracking Prevention

This new feature of macOS High Sierra and iOS 11 deactivates third-party cookies every 24 hours, unless the user interacts with one of the page of the domain of the third-party. As the Google Sign-in library relies on cookies to securely authenticate the user, it will potentially detect that the user is logged out every 24 hours. The user has to go through the sign in flow again to reactivate the cookies.

Yeah, i believe that might cause the issue. Do you have any suggested workaround? Disabling prevent cross-site tracking not an ideal solution. I want to fix this on js.

Any update? I'm running into this issue on Safari 13.0.3, but not on version 11.1.1

Same issue. Need help!

I think the ITP 2.0 is the main cause for this issue. https://webkit.org/blog/8311/intelligent-tracking-prevention-2-0/

This explains why Safari Private Mode works, because it is considered a clean browser context and google.com is not (yet) identified as a tracking domain by ITP.

It should work if the signIn() is called and the user interacted with the popup, given the temporary compatibility fix in ITP 2.0 (https://webkit.org/blog/8311/intelligent-tracking-prevention-2-0, search for "temporary")

anyone find a work around for this?

See #260

See my comment here. May help in your case

To resolve it, I've had to add some extra steps in my auth method.

You'll need to use the "redirect" method for the Google Signin: I found that it works better across different browsers and platforms. When the user will sign in, Google will redirect to the original website with some parameters in the hash of the URL, and we'll need them to proceed.

So I check the URL to see if I have some tags:

let hash = window.location.hash || window.top.location.hash;
(hash ? hash.slice(1).split('&').map(param => { let [ id, value ] = param.split("="); return {id, value} }) : []).forEach(param => {
  this.hashParams[param.id] = decodeURIComponent(param.value); // I store it in `this.hasParams`
});

Then I dynamically load the JS file from Google:

let a = window.document.createElement('script');
a.type = 'text/javascript';
a.async = true;
a.defer = true;
a.src = 'https://apis.google.com/js/platform.js?onload=onGoogleLoginReady';
window.document.getElementById('google-root').appendChild(a);

When the script is loaded it will call onGoogleLoginReady:

window.onGoogleLoginReady = () => {
  window.gapi.load('auth2', () => {
    // https://developers.google.com/identity/sign-in/web/reference
    this.googleAuth = window.gapi.auth2.init({
      ux_mode:'redirect', // here I use the "redirect" method to make sure it works across different browsers
      redirect_uri:this.getRedirectUrl('google')
    }));
    this.googleIsReady = true;
    // wait for the GoogleAuth object to be initiated
    this.googleAuth.then(() => {
      // when the user gets back to the website after being signed in by Google,
      // `isSignedIn.get()` should return TRUE
      if (this.googleAuth.isSignedIn.get()) {
        this.onGoogleSignInSuccess(this.googleAuth.currentUser.get());
      } else {
        // for Safari iOS isSignedIn.get() will return FALSE
        // however an 'id_token' is provided in the URL when we're getting back from Google Signin page
        // so I check if the `id_token` is provided (you can also check some other parameters)
        if (this.hashParams.id_token) {
          // I'm sending this 'id_token' to my server that will do the below:
          //   1. send a request to "https://oauth2.googleapis.com/tokeninfo?id_token=" + id_token
          //   2. check if 'aud' from the response is the same as my Google Client ID (see https://developers.google.com/identity/sign-in/web/backend-auth)
          //   3. return the response from Google to the client 
          this.http("/my_server/check_googleapis_tokeninfo/", {id_token:this.hashParams.id_token})
          .then(res => {
            if (res.body && res.body.email_verified && res.body.email) {
              // in my `onGoogleSignInSuccess` I only need the `id_token` and `profile.getEmail()`
              // so I provide them as the second parameter
              this.onGoogleSignInSuccess(false, {
                id_token: this.hashParams.id_token,
                profile:{
                  getEmail:() => res.body.email
                }
              });
            }
          })
        }
      }
    });
  });

Now my success function (onGoogleSignInSuccess) can deal with the email provided by the Google SignIn process, even for Safari iOS.

Was this page helpful?
0 / 5 - 0 ratings