【问题标题】:connect html button to access google's people API连接 html 按钮以访问谷歌的人员 API
【发布时间】:2019-08-13 03:08:58
【问题描述】:

我的 HTML 正文中有一个按钮,当用户单击该按钮时,它应该加载用户的谷歌联系人。我已经通过 Google Cloud Platform 注册了所需的凭据和授权,但由于某种原因,我拥有的 javascript 代码无法正常工作,并且在 Visual Studio 的演示模式下单击按钮不会打开一个新窗口,要求我登录到我的gmail 帐户,网站访问我的联系人的权限等。任何帮助使 API 在我的网站上工作将不胜感激。

<button id="google-button" onclick="return auth()" style="color:white;background-color:royalblue;margin:20px;padding:5px 10px;border-style:solid;font-weight:bold">Share to all of your Google contacts</button>
                    <script>                        
                        function auth() {
                            const fs = require('fs');
                            const readline = require('readline');
                            const { google } = require('googleapis');

                            // If modifying these scopes, delete token.json.
                            const SCOPES = ['https://www.googleapis.com/auth/contacts.readonly'];
                            // The file token.json stores the user's access and refresh tokens, and is
                            // created automatically when the authorization flow completes for the first
                            // time.
                            const TOKEN_PATH = 'token.json';

                            // Load client secrets from a local file.
                            fs.readFile('credentials.json', (err, content) => {
                                if (err) return console.log('Error loading client secret file:', err);
                                // Authorize a client with credentials, then call the Google Tasks API.
                                authorize(JSON.parse(content), listConnectionNames);
                            });

                            function authorize(credentials, callback) {
                                const { client_secret, client_id, redirect_uris } = credentials.installed;
                                const oAuth2Client = new google.auth.OAuth2(
                                    client_id, client_secret, redirect_uris[0]);

                                // Check if we have previously stored a token.
                                fs.readFile(TOKEN_PATH, (err, token) => {
                                    if (err) return getNewToken(oAuth2Client, callback);
                                    oAuth2Client.setCredentials(JSON.parse(token));
                                    callback(oAuth2Client);
                                });
                            }

                            function getNewToken(oAuth2Client, callback) {
                                const authUrl = oAuth2Client.generateAuthUrl({
                                    access_type: 'offline',
                                    scope: SCOPES,
                                });
                                console.log('Authorize this app by visiting this url:', authUrl);
                                const rl = readline.createInterface({
                                    input: process.stdin,
                                    output: process.stdout,
                                });
                                rl.question('Enter the code from that page here: ', (code) => {
                                    rl.close();
                                    oAuth2Client.getToken(code, (err, token) => {
                                        if (err) return console.error('Error retrieving access token', err);
                                        oAuth2Client.setCredentials(token);
                                        // Store the token to disk for later program executions
                                        fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
                                            if (err) return console.error(err);
                                            console.log('Token stored to', TOKEN_PATH);
                                        });
                                        callback(oAuth2Client);
                                    });
                                });
                            }

                            function listConnectionNames(auth) {
                                const service = google.people({ version: 'v1', auth });
                                service.people.connections.list({
                                    resourceName: 'people/me',
                                    pageSize: 10,
                                    personFields: 'names,emailAddresses',
                                }, (err, res) => {
                                    if (err) return console.error('The API returned an error: ' + err);
                                    const connections = res.data.connections;
                                    if (connections) {
                                        console.log('Connections:');
                                        connections.forEach((person) => {
                                            if (person.names && person.names.length > 0) {
                                                console.log(person.names[0].displayName);
                                            } else {
                                                console.log('No display name found for connection.');
                                            }
                                        });
                                    } else {
                                        console.log('No connections found.');
                                    }
                                });
                            }
                        }
                    </script>

【问题讨论】:

    标签: javascript node.js button google-people-api


    【解决方案1】:

    &lt;script&gt; 标记中的代码是服务器端 Node.js 代码,而不是客户端 JavaScript。它不会在浏览器中运行,因为:

    • require('fs') 导入文件系统模块,但在 Node.js 之外不存在这样的东西。
    • readlinegoogleapis 也是特定于 Node 的模块,因此它们在客户端 JS 中没有任何意义,如果 require 还没有,它们可能会抛出错误。
    • fs.readFile(...) 尝试使用 fs 模块(见上文)读取特定路径的文件,但客户端 JavaScript 无权访问文件系统。
    • 从根本上说,OAuth 协商应该在服务器上处理,而不是在客户端上。通常,特权请求将使用数据库中的数据,如果令牌存储在客户端上,则无法做到这一点。

    这里的主要问题似乎是对 OAuth 是什么以及它如何工作的混淆。以下是该过程的简化分步演练:

    1. 用户从其客户端登录到外部服务。
    2. 外部服务生成一个代码(一个token)并发送给客户端。
    3. 客户端接收令牌(在回调、哈希参数等中)并将其发送到您的服务器。大多数情况下,外部服务会简单地将客户端重定向到服务器上的 URL,并使用查询字符串中的令牌,让您从请求中获取它。
    4. 您的服务器将特定用户帐户的令牌存储在您的数据库中。
    5. 对于特权操作,您的服务器将请求发送到外部服务并包含令牌。
    6. 服务器使用令牌接收您的请求并代表用户执行操作。

    当外部服务收到带有令牌的请求时,它会查找该令牌并查看它属于特定用户。因为该用户必须登录并授权您的应用才能创建令牌,所以服务知道它应该继续执行该操作。

    OAuth 令牌可能是永久性的,但更常见的情况是,它们会在一段时间后过期并且必须重新生成。这意味着您应该从不将令牌用作识别用户的主键。至于如何重新生成过期令牌,具体细节因提供商而异。您正在使用的服务(在本例中为 Google)将提供有关其身份验证流程如何工作以及应如何处理刷新的更多信息。

    【讨论】:

      猜你喜欢
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      相关资源
      最近更新 更多