连接HTML按钮以访问Google的People API

时间:2019-08-13 03:08:58

标签: javascript node.js button google-people

我的HTML正文中有一个按钮,当用户单击该按钮时,该按钮应该会加载用户的google联系人。我已经通过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>

1 个答案:

答案 0 :(得分:1)

<script>标记中的代码是服务器端Node.js代码,而不是客户端JavaScript。它在浏览器中将无法运行,因为:

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

这里的主要问题似乎是关于什么是OAuth及其工作方式的困惑。这是该过程的简化分步演练:

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

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

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