连接HTML按钮以访问Google的人员API [英] connect html button to access google's people API

查看:83
本文介绍了连接HTML按钮以访问Google的人员API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a button in my HTML body, which is supposed to load a user's google contacts when a user clicks the button. I've registered for the required credentials and authorization via Google Cloud Platform, but for some reason, the javascript code I have is not working and clicking the button in demo mode in Visual studio does not open a new window asking me to login into my gmail account, permission for the website to access my contacts, etc. Any help in getting the API to work on my website will be much appreciated.

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


推荐答案

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

The code in your <script> tag is server-side Node.js code, not client-side JavaScript. It will not function in the browser because:


  • require('fs')导入文件系统模块,但在Node.js外部不存在此类东西。

  • readline googleapis 也是特定于节点的模块,因此它们在客户端JS中没有意义,如果 require 尚未,它们可能会抛出错误。

  • fs.readFile(...)尝试使用fs模块(请参见上文)在特定路径下读取文件,但是客户端JavaScript无法访问文件系统。

  • 从根本上讲,OAuth协商应在服务器上而不是在客户端上进行。通常,特权请求将使用数据库中的数据,如果令牌存储在客户端上则无法执行。

  • require('fs') imports the filesystem module, but no such thing exists outside of Node.js.
  • readline and googleapis are also Node-specific modules, so they have no meaning in client-side JS and will probably throw errors if require hasn't already.
  • fs.readFile(...) attempts to use the fs module (see above) to read a file at a certain path, but client-side JavaScript doesn't have access to the filesystem.
  • Fundamentally, OAuth negotiation should be handled on the server, not on the client. Typically, a privileged request will use data from your database, which it cannot do if the token is stored on the client.

就像这里的主要问题一样,是关于什么是OAuth及其工作方式的困惑。这是该过程的简化分步操作:

It seems like the main problem here is confusion about what OAuth is and how it works. Here's a simplified step-by-step walkthrough of the process:


  1. 用户从其客户端登录到外部服务。

  2. 外部服务会生成一个代码(一个令牌)并将其发送给客户端。

  3. 客户端会收到令牌(在回调,哈希参数等)并将其发送到您的服务器。通常,外部服务会简单地将客户端重定向到服务器上带有查询字符串中的令牌的URL,从而使您可以从请求中获取令牌。

  4. 您的服务器存储令牌对于数据库中的特定用户帐户。

  5. 对于特权操作,服务器将请求发送到外部服务并包括令牌。

  6. 服务器收到带有令牌的请求,并代表用户执行操作。

  1. The user logs into an external service from their client.
  2. The external service generates a code (a token) and sends it to the client.
  3. The client receives the token (in a callback, hash param, etc.) and sends it to your server. Most often the external service will simply redirect the client to a URL on your server with the token in the query string, allowing you to grab it out of the request.
  4. Your server stores the token for a specific user account in your database.
  5. For privileged actions, your server sends the request to the external service and includes the token.
  6. The server receives your request with the token and performs an action on the user's behalf.

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

When the external service receives a request with a token, it looks up that token and sees that it belongs to a specific user. Because that user must have logged in and authorized your app in order to create the token, the service knows that it should proceed with the action.

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

OAuth tokens may be permanent, but much more often they will expire after a set period of time and have to be regenerated. This means that you should never be using the token as a primary key to identify a user. As for how to regenerate an expired token, the exact details vary by provider. The service you're using (Google, in this case) will have more information on how their auth flow works, and how refreshing should be handled.

这篇关于连接HTML按钮以访问Google的人员API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆