gapi login state not retained in users browser aft

2020-07-16 08:02发布

问题:

I've dove into a small project aiming to utilize the YouTube API. I've got some basic code in place, that I initially thought was, working properly.

Using Chrome, I can login through multiple machines on my own network without any issues using the source below. I've also tethered my machines to my cellular network to ensure that the process also works properly outside of my own network.

Unfortunately, I'm having issues finding out why a colleague (from a remote location) is unable to retain his login state between page refreshes after successfully logging in through Chrome, although no issues are apparent when using Firefox.

For an example of a successful scenario, when loading the page for the first time, the callback assigned to authInstance.isSignedIn.listen is called with a value of true if the user has already logged in.

On my colleagues machine, the authInstance.isSignedIn.listen listener is not called after refreshing the page after successfully logging in, indicating no login.

I'm currently not using an SSL certificate, if that information helps any.

Additional information includes my colleagues ability to authenticate and retain login state without any issues on other sites that support YouTube authentication. I've been unable to look through the source of those sites, as the source is obfuscated.

Here's my own source:

<html lang="en">
<head>
    <script src="https://apis.google.com/js/platform.js?onload=onLoad" async defer></script>
</head>
<body>
    <button id="sign-in">Sign In</button>
    <button id="sign-out">Sign Out</button>
    <script>
        var authInstance;
        var signInBtn = document.getElementById('sign-in');
        var signOutBtn = document.getElementById('sign-out');

        function onLoad() {
            gapi.load('auth2', function() {
                console.log('loadAuth2()');
                auth2 = gapi.auth2.init({
                    client_id: '[CLIENT_ID]',
                });

                authInstance = gapi.auth2.getAuthInstance();
                authInstance.isSignedIn.listen(function () {
                    console.log('authUpdate()');
                    console.log(arguments);
                });
            });
        }

        signInBtn.onclick = function () {
            console.log('signInBtn onclick()');

            /*

            Signing in this way produces the same results.

            auth2.grantOfflineAccess({
              scope: "https://www.googleapis.com/auth/youtube.readonly",
              redirect_uri: "postmessage"
            }).then(function () {
                console.log("accessGranted() (?)");
                console.log(arguments);
            });

            */

            auth2.signIn({
                scope: "https://www.googleapis.com/auth/youtube",
            }).then(function () {
                console.log('signedIn()');
                console.log(arguments);
            });
        };

        signOutBtn.onclick = function () {
            console.log('signOutBtn onclick()');
            authInstance.signOut();
        };
    </script>
</body>
</html>

回答1:

I'm not an expert in Google Sign-In, in my experience, however, the following code did not work.

authInstance = gapi.auth2.getAuthInstance();
console.log(authInstance.isSignedIn.get());

Instead, you should do like:

authInstance = gapi.auth2.getAuthInstance();
authInstance.then(function() {  // onInit
  console.log(authInstance.isSignedIn.get());
}, function() {  // onError
});

You should wait until the GoogleAuth object is fully initialized.



回答2:

This is how I got it to work with a custom button which you attach the event to. Yes its very important to await some of these functions as mentioned by other answers, as perhaps not everything has loaded untill they have been awaited

async function initializeGoogleStuff() {
  window.gapi.load('auth2', async () => {
    window.auth2 = await window.gapi.auth2.init({
      prompt: "select_account",
    })

    var authInstance = await window.gapi.auth2.getAuthInstance();
    var signedIn = authInstance.isSignedIn.get()
    if (signedIn) {
      // handleLogin is my own function for calling our backend server
      //  and doing other login related stuff
      await handleLogin(authInstance.currentUser.get())
    }

    // I am using a custom button with attachClickHandler()
    // https://developers.google.com/identity/sign-in/web/reference#googleauthattachclickhandlercontainer_options_onsuccess_onfailure
    let signInElement = window.document.getElementById("signInButton")
    if (signInElement) {
      attachElementToCallback(signInElement, handleLogin)
    }

 })               
}