简体   繁体   English

通过服务帐户访问 Google Drive:错误:需要登录

[英]Access to Google Drive through Service Account : Error: Login Required

const {google} = require('googleapis');
let drive = google.drive('v3');

exports.handler = async (req, res) => {
    res.set('Access-Control-Allow-Origin', '*')
      .set('Access-Control-Allow-Methods', 'POST')
    .status(200);
  var privatekey 
  var jwtClient 
  await global.admin.database().ref(`g_drive_token/OfficServiceAccount`).once('value').then((doc)=> {
    privatekey = doc.val()
    jwtClient = new google.auth.JWT(
      privatekey.client_email,
      null,
      privatekey.private_key,
      ['https://www.googleapis.com/auth/drive.file'],
      null);
      console.log(JSON.stringify(jwtClient))   
      authWithServicePrivateKey(jwtClient)
      return "null"
    }) .catch((error)=> {            
    console.log('Error fetching user data:+', error);
      return "null"
  }) 


function authWithServicePrivateKey(jwtClient){
  //authenticate request
jwtClient.authorize(function (err, tokens) {
    if (err) {
      console.log("Could not connect***!"+err);
      return;
    } else {
      console.log("Successfully connected!");
      console.log('token******'+JSON.stringify(tokens))
      listFolderInGoogleDrive()
      CreateFolderInGoogleDrive()
    }
   });
}


//Google Drive API
function listFolderInGoogleDrive() {
    console.log('listFolderInGoogleDrive() was called')
    drive.files.list({
        auth: jwtClient,
        pageSize: 10,
        fields: 'nextPageToken, files(id, name)',
      }, (err, res) => {
        if (err) return console.log('The API returned an error: ' + err);
        console.log(JSON.stringify(res.data))
        console.log(JSON.stringify(res.data.files))
        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.');
        }
      });
    }

    function  CreateFolderInGoogleDrive() {
        console.log('CreateFolderInGoogleDrive() was called')
        var fileMetadata = {
            auth: jwtClient,
            'name': 'OfficService',
            'mimeType': 'application/vnd.google-apps.folder',
            'parents':['12CCq1GGoTyDW_Ox09TZf5BDgaPAjB0AR']
          };
          drive.files.create({
            resource: fileMetadata,
            fields: 'id'
          },(err, file)=> {
            if (err) {
              // Handle error
              console.error(err);
            } else {
             console.log('***parent****'+ file.data.id) 
           
            }
          });
        }

Note: Drive folder "12CCq1GGoTyDW_Ox09TZf5BDgaPAjB0AR" is already shared with Service account email ID.注意:驱动器文件夹“12CCq1GGoTyDW_Ox09TZf5BDgaPAjB0AR”已与服务帐户 email ID 共享。

Here are some of the results of console log that reflect where it failed.以下是控制台日志的一些结果,这些结果反映了它失败的位置。

token******{"access_token":"**********","token_type":"Bearer","expiry_date":1593865140000,"refresh_token":"jwt-placeholder"} token******{"access_token":"**********","token_type":"Bearer","expiry_date":1593865140000,"refresh_token":"jwt-placeholder"}

listFolderInGoogleDrive() was called listFolderInGoogleDrive() 被调用

CreateFolderInGoogleDrive() was called CreateFolderInGoogleDrive() 被调用

Error: Login Required错误:需要登录

I guess, I am not using token to authenticate.我想,我没有使用令牌进行身份验证。 Please help me with Node.js code to use this token to authenticate service account.请帮助我使用 Node.js 代码来使用此令牌来验证服务帐户。

I would like to modify the following modification.我想修改以下修改。

Modification points:修改点:

  • At exports.handler = async (req, res) => {} , the last } is not used.exports.handler = async (req, res) => {}中,最后一个}没有被使用。 So your script is not complete.所以你的脚本不完整。 Please be careful this.请注意这一点。
    • From your question, I thought that this might be the miss-copy of the script.根据您的问题,我认为这可能是脚本的错误副本。
  • In your script, jwtClient is not used at listFolderInGoogleDrive() and CreateFolderInGoogleDrive() .在您的脚本中, jwtClient不在listFolderInGoogleDrive()CreateFolderInGoogleDrive()中使用。 I thought that this might be the reason of your issue.我认为这可能是您的问题的原因。
  • At CreateFolderInGoogleDrive() , auth: jwtClient is required to be used in the object of {resource: fileMetadata, fields: "id"} .CreateFolderInGoogleDrive()中,需要在{resource: fileMetadata, fields: "id"}的 object 中使用auth: jwtClient
    • But in this case, I would like to propose to include jwtClient in drive like google.drive({ version: "v3", auth: jwtClient }) .但在这种情况下,我想建议在google.drive({ version: "v3", auth: jwtClient })之类的drive中包含jwtClient

When above points are reflected to your script, it becomes as follows.当以上几点反映到您的脚本时,它变成如下。 In this case, the functions of authWithServicePrivateKey , listFolderInGoogleDrive and CreateFolderInGoogleDrive are modified.在这种情况下,修改了authWithServicePrivateKeylistFolderInGoogleDriveCreateFolderInGoogleDrive的功能。

Modified script:修改后的脚本:

function authWithServicePrivateKey(jwtClient) {
  // Modified
  jwtClient.authorize(function (err) {
    if (err) {
      console.log("Could not connect***!" + err);
      return;
    }
  });
  drive = google.drive({ version: "v3", auth: jwtClient }); // Added
  listFolderInGoogleDrive();
  CreateFolderInGoogleDrive();
}

//Google Drive API
function listFolderInGoogleDrive() {
  console.log("listFolderInGoogleDrive() was called");
  drive.files.list(
    {
      //   auth: jwtClient,  // Removed
      pageSize: 10,
      fields: "nextPageToken, files(id, name)",
    },
    (err, res) => {
      if (err) return console.log("The API returned an error: " + err);
      console.log(JSON.stringify(res.data));
      console.log(JSON.stringify(res.data.files));
      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.");
      }
    }
  );
}

function CreateFolderInGoogleDrive() {
  console.log("CreateFolderInGoogleDrive() was called");
  var fileMetadata = {
    // auth: jwtClient,  // Removed
    name: "OfficService",
    mimeType: "application/vnd.google-apps.folder",
    parents: ['12CCq1GGoTyDW_Ox09TZf5BDgaPAjB0AR'],
  };
  drive.files.create(
    {
      resource: fileMetadata,
      fields: "id",
    },
    (err, file) => {
      if (err) {
        // Handle error
        console.error(err);
      } else {
        console.log("***parent****" + file.data.id);
      }
    }
  );
}

Note:笔记:

  • In this modification, it supposes that you have already been able to get and put values for Google Drive using Drive API with your service account.在此修改中,假设您已经能够使用 Drive API 和您的服务帐户获取和放置 Google Drive 的值。 Please be careful this.请注意这一点。

Added:添加:

When you want to retrieve the file list of the files you created manually, please modify the scope as follows.当您要检索您手动创建的文件的文件列表时,请按如下方式修改 scope。

From:从:

['https://www.googleapis.com/auth/drive.file'],

To:至:

['https://www.googleapis.com/auth/drive'],
  • About the scope of https://www.googleapis.com/auth/drive.file , the official document says as follows.关于https://www.googleapis.com/auth/drive.file的 scope ,官方文档是这样说的。

    Per-file access to files created or opened by the app.对应用程序创建或打开的文件的按文件访问。 File authorization is granted on a per-user basis and is revoked when the user deauthorizes the app.文件授权是按用户授予的,并在用户取消对应用程序的授权时撤销。

And also, you want to retrieve the file list of only the shared folder of 12CCq1GGoTyDW_Ox09TZf5BDgaPAjB0AR , please modify as follows.另外,如果您想只检索12CCq1GGoTyDW_Ox09TZf5BDgaPAjB0AR的共享文件夹的文件列表,请进行如下修改。

From:从:

drive.files.list({
    auth: jwtClient,
    pageSize: 10,
    fields: 'nextPageToken, files(id, name)',
  }, (err, res) => {

To:至:

drive.files.list({
    auth: jwtClient,
    pageSize: 10,
    fields: 'nextPageToken, files(id, name)',
    q: "'12CCq1GGoTyDW_Ox09TZf5BDgaPAjB0AR' in parents",  // Added
  }, (err, res) => {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Google登录-尝试访问userinfo时出现401错误“需要登录” - Google Login - 401 error “Login Required” when trying to access userinfo Google Drive API - 服务帐户凭据无效 - Google Drive API - Invalid service account credentials 域内的Google Drive API服务帐户 - Google Drive API Service Account inside domain 使用服务帐户访问Google Container构建器日志 - 403 Forbidden Error - Access Google Container builder logs with a service account - 403 Forbidden Error 无法通过谷歌电子表格中的服务帐户访问权限写入 api (node.js) - Unable to write through service account access in google spread sheet api (node js) 将驱动器权限授予Google Developer Console中的服务帐户 - Give drive permission to service account in Google Developer Console 使用服务帐户密钥访问Google数据存储区 - Google Datastore access using Service Account Keys 是否可以通过安心的服务使用其Facebook帐户登录某人? - Is it possible to login someone with their facebook account through a restful service? 将Google云端硬盘备份到另一个Google云端硬盘帐户 - Backup google drive to another google drive account 获取服务器到服务器的访问权限(Google服务帐户)令牌。 invalid_grant错误 - Getting a server to server access (google service account) token. invalid_grant error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM