在前端授权的情况下,从nodejs后端调用谷歌驱动api



我目前有一个应用程序,要求我从客户端和服务器调用google驱动器api。现在,我已经在前端使用auth2.0对用户进行了身份验证,我可以很好地上传文件。

本节的大部分代码,我都是从文档和各种博客文章中拼凑出来的。

async function uploadDocGoogle() {
// get file
const fileChooser = document.getElementById('config-file-upload');
const file = fileChooser.files[0];

console.log("file", file);

const fileMetaData = {
'name': file.name,
'mimeType': file.type
};
var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
await setGoogleAPIToken(accessToken);
console.log(accessToken);
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(fileMetaData)], {type: 'application/json'}));
form.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id');
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.responseType = 'json';
xhr.onload = () => {
console.log(xhr.response.id); // Retrieve uploaded file ID.
console.log(xhr);
};
xhr.send(form);
}
var SCOPES = 'https://www.googleapis.com/auth/drive';
var authorizeButton = document.getElementById('config-google-test');
/**
*  On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
/**
*  Initializes the API client library and sets up sign-in state
*  listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
//authorizeButton.onclick = handleAuthClick;
}, function(error) {
appendPre(JSON.stringify(error, null, 2));
});
}
/**
*  Called when the signed in status changes, to update the UI
*  appropriately. After a sign-in, the API is called.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
console.log("Logged In");
} else {
console.log("Logged Out");
}
}
/**
*  Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
/**
*  Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}

现在我需要从NodesJS编写的后端调用api。然而,我想使用我从前端已经拥有的东西来授权这些呼叫。在前端为调用生成的auth令牌似乎只是临时的,所以我认为我不能将其发送到后端来授权调用。我想知道是否有人知道另一种方法?我想知道是否有人也知道如何初始化谷歌api来使用该令牌进行调用。

您可以在NodeJS中使用passport来集成google auth 2.0,然后在前端使用它来验证和登录用户。用户登录后,您将获得一个包含其他用户数据(姓名、电子邮件等(的令牌(来自googleauth(。然后,您可以将其存储在数据库(或服务器变量/json文件(中。

现在,您可以使用会话来保存用户状态,或者简单地调用所需的带有令牌的api(在前端维护其状态,React Hooks?或者简单地使用cookie(,然后您可以验证它是哪个用户。

这是一个粗略的解决方案。但我也以类似的方式与之合作。

下面试试:

const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];
const TOKEN_PATH = 'token.json';// You can save token in dB as well
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 Drive API.
authorize(JSON.parse(content), listFiles);
});
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 getAccessToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
function getAccessToken(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 listFiles(auth) {
const drive = google.drive({version: 'v3', auth});
drive.files.list({
pageSize: 10,
fields: 'nextPageToken, files(id, name)',
}, (err, res) => {
if (err) return console.log('The API returned an error: ' + err);
const files = res.data.files;
if (files.length) {
console.log('Files:');
files.map((file) => {
console.log(`${file.name} (${file.id})`);
});
} else {
console.log('No files found.');
}
});
}

如果您想使用前端,可以简化"getAccessToken"。当你将获得一个帐户授权谷歌。谷歌会还给你一个代码。在此函数中使用该代码。这将实现你的目标。

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);
});
});

最新更新