使用前端的授权从Node.js后端调用Google Drive API [英] Calling google drive api from nodejs backend with authorisation from front end

查看:146
本文介绍了使用前端的授权从Node.js后端调用Google Drive API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I currently have an application that requires me to call the google drive api from the client and the server. Right now, I've already authenticated the user on the front end with auth 2.0 and I can upload files just fine.

本节的大多数代码,都是我从文档和各种博客文章中搜集来的.

Most of the code for this section, I've scraped together from the documentation and various blog posts.

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令牌似乎只是临时的,因此我认为我无法将其发送到后端以授权呼叫.我想知道是否有人知道另一种方法?我想知道是否有人还知道如何初始化Google API以使用该令牌进行呼叫.

Now I need to make a call to the api from the backend written in NodesJS. However, I want to authorize these calls using what I already have from the front end. The auth token that is generated in the front end for the call seems to only be temporary and so I don't think i can send that to the backend to authorize calls. I was wondering if anyone knew another way to do it? I was wondering if anyone also knew how to initialise the google api to use that token to make a call.

推荐答案

尝试以下方法:

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'.当您获得一个帐户授权给Google时. Google会退还给您一个验证码.在此函数中使用该代码.这将实现您的目标.

'getAccessToken' can be simplified if you want to use front-end. When you will get a account authorize to google. Google will return back you a Code. Use that code in this function. This will achieve your objective.

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

这篇关于使用前端的授权从Node.js后端调用Google Drive API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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