Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gapi auth2 issue on safari #503

Open
shahazaryan opened this issue Feb 1, 2019 · 21 comments
Open

gapi auth2 issue on safari #503

shahazaryan opened this issue Feb 1, 2019 · 21 comments

Comments

@shahazaryan
Copy link

shahazaryan commented Feb 1, 2019

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

@shahazaryan
Copy link
Author

???????

@xueligoh
Copy link

xueligoh commented Jun 7, 2019

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.

@ddomonkos
Copy link

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?

@kotaro44
Copy link

kotaro44 commented Jul 26, 2019

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!

@kotaro44
Copy link

@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!

@timperkins
Copy link

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

@kotaro44
Copy link

kotaro44 commented Aug 8, 2019

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.

@shahazaryan
Copy link
Author

shahazaryan commented Aug 8, 2019 via email

@sanjosedennisns7593
Copy link

Any update? Same case on my end.

@MathiasGilson
Copy link

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.

@sanjosedennisns7593
Copy link

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.

@brada1703
Copy link

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

@khaight
Copy link

khaight commented Mar 1, 2020

Same issue. Need help!

@wasyyyy
Copy link

wasyyyy commented Mar 4, 2020

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")

@cor1
Copy link

cor1 commented Mar 12, 2020

anyone find a work around for this?

@jsejcksn
Copy link

See #260

@yuzhakovvv
Copy link

See my comment here. May help in your case

@Aymkdn
Copy link

Aymkdn commented Sep 6, 2020

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.

@Resousse
Copy link

Resousse commented Jul 1, 2021

Thanks @Aymkdn for this solution, but how do you persist the authentication to be available after a page refresh?

@Aymkdn
Copy link

Aymkdn commented Jul 1, 2021

Thanks @Aymkdn for this solution, but how do you persist the authentication to be available after a page refresh?

After the success of the authentication, it's managed by the Google library (I guess they use a cookie).

@Resousse
Copy link

Resousse commented Jul 1, 2021

Thanks @Aymkdn for this solution, but how do you persist the authentication to be available after a page refresh?

After the success of the authentication, it's managed by the Google library (I guess they use a cookie).

Thanks for you quick reply!
Arf, doesn't work for me, I think this is linked to the broken "GoogleAuth.isSignedIn.get()"...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests