如何将“使用 Google 登录”与 TokenClient 结合使用?

Flo*_*aus 7 javascript google-oauth google-cloud-platform google-identity

我阅读了使用 Google 登录指南Google Identity Services JavaScript SDK 指南中的信息和示例,并成功使用 Google Cloud API 的令牌设置了授权。不幸的是,即使在首次登录时获得用户同意后,每次加载页面时我仍然会收到登录提示,要求选择我的 Google 帐户。

我看到requestAccessToken允许指定用户电子邮件作为登录hint方式OverridableTokenClientConfig,但即使我指定,每次运行hint时我仍然会收到登录提示。requestAccessToken

最终,我想使用“使用Google 登录”来允许用户自动登录并向应用程序提供电子邮件等用户信息。然后requestAccessToken应该使用该电子邮件请求令牌,而无需再次提示用户(除非用户第一次需要同意范围devstorage.full_control)。

这是我当前使用的代码(要运行它,您需要插入有效的 clientId、bucket 和对象):

<html>
  <head>
    <!-- Google Identity Service see https://developers.google.com/identity/oauth2/web/guides/migration-to-gis#gis-and-gapi -->
    <script src="https://accounts.google.com/gsi/client" onload="initTokenClient()" async defer></script>
    <script>
        var tokenClient;
        var access_token;
        var clientId = '123456789012-abcdefghijklmnopqrstuvxyz123456.apps.googleusercontent.com';
        var email = 'florian.feldhaus@gmail.com'
        var bucket = 'private-bucket'
        var object = 'private-object.json'

        function initTokenClient() {
            tokenClient = google.accounts.oauth2.initTokenClient({
                client_id: clientId,
                scope: 'https://www.googleapis.com/auth/devstorage.full_control',
                callback: (tokenResponse) => {
                    access_token = tokenResponse.access_token;
                },
            });
        }

        function getToken() {
            // Re-entrant function to request user consent.
            // Returns an access token to the callback specified in google.accounts.oauth2.initTokenClient
            // Use a user gesture to call this function and obtain a new, valid access token
            // when the previous token expires and a 401 status code is returned by Google API calls.
            tokenClient.requestAccessToken({
                    hint: email
                }
            );
        }

        function getObject() {
            fetch('https://storage.googleapis.com/storage/v1/b/' + bucket + '/o/' + object + '?alt=media', {
               headers: {
                   'Authorization': 'Bearer ' + access_token
                }
            })
            .then(response => response.json())
            .then(content => console.log(content))
            .catch(err => { console.log(err) });
        }
    </script>
  </head>
  <body>      
    <button onclick="getToken();">Get access token</button>
    <button onclick="getObject()">Load Object</button>    
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

获取访问令牌总是会打开这样的登录提示

登录提示

Flo*_*aus 7

可以通过prompt在 中设置空参数initTokenClient来阻止登录提示。这只会在首次登录时提示登录并征得用户同意。所有后续登录都将使用第一次登录时选择的帐户。这仍然短暂地显示一个带有旋转轮的弹出窗口,通常会在一秒钟内消失。

如果有人有更多关于如何摆脱弹出窗口并与“使用 Google 登录”集成的信息要分享,请作为单独的答案分享。

我的完整示例现在如下所示(删除hint并添加prompt):

<html>
  <head>
    <!-- Google Identity Service see https://developers.google.com/identity/oauth2/web/guides/migration-to-gis#gis-and-gapi -->
    <script src="https://accounts.google.com/gsi/client" onload="initTokenClient()" async defer></script>
    <script>
        var tokenClient;
        var access_token;
        var clientId = '123456789012-abcdefghijklmnopqrstuvxyz123456.apps.googleusercontent.com';
        var email = 'florian.feldhaus@gmail.com'
        var bucket = 'private-bucket'
        var object = 'private-object.json'

        function initTokenClient() {
            tokenClient = google.accounts.oauth2.initTokenClient({
                client_id: clientId,
                scope: 'https://www.googleapis.com/auth/devstorage.full_control',
                prompt: '',
                callback: (tokenResponse) => {
                    access_token = tokenResponse.access_token;
                },
            });
        }

        function getToken() {
            // Re-entrant function to request user consent.
            // Returns an access token to the callback specified in google.accounts.oauth2.initTokenClient
            // Use a user gesture to call this function and obtain a new, valid access token
            // when the previous token expires and a 401 status code is returned by Google API calls.
            tokenClient.requestAccessToken();
        }

        function getObject() {
            fetch('https://storage.googleapis.com/storage/v1/b/' + bucket + '/o/' + object + '?alt=media', {
               headers: {
                   'Authorization': 'Bearer ' + access_token
                }
            })
            .then(response => response.json())
            .then(content => console.log(content))
            .catch(err => { console.log(err) });
        }
    </script>
  </head>
  <body>      
    <button onclick="getToken();">Get access token</button>
    <button onclick="getObject()">Load Object</button>    
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)