我的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>
答案 0 :(得分:1)
<script>
标记中的代码是服务器端Node.js代码,而不是客户端JavaScript。它在浏览器中将无法运行,因为:
require('fs')
导入文件系统模块,但在Node.js之外不存在此类东西。readline
和googleapis
也是特定于节点的模块,因此它们在客户端JS中没有意义,如果require
尚未出现,它们可能会抛出错误。fs.readFile(...)
尝试使用fs模块(请参见上文)从某个路径读取文件,但是客户端JavaScript无法访问该文件系统。这里的主要问题似乎是关于什么是OAuth及其工作方式的困惑。这是该过程的简化分步演练:
当外部服务收到带有令牌的请求时,它将查找该令牌并发现它属于特定用户。由于该用户必须已登录并授权您的应用才能创建令牌,因此该服务知道应继续执行该操作。
OAuth令牌可能是永久性的,但更常见的是,它们会在设定的时间段后过期并必须重新生成。这意味着您应该从不将令牌用作识别用户的主键。至于如何重新生成过期的令牌,具体细节因提供商而异。您正在使用的服务(在这种情况下为Google)将提供有关其身份验证流程如何工作以及应该如何处理刷新的更多信息。