当前位置: 首页 > 知识库问答 >
问题:

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

史修明
2023-03-14
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) 
           
            }
          });
        }

注意:驱动器文件夹“12 ccq 1 ggotydw _ ox 09 tzf 5 bdgapajb 0 ar”已与服务帐户电子邮件ID共享。

以下是控制台日志的一些结果,反映了失败的位置。

token * * * * * * * * * { " access _ token ":" * * * * * * * * * * * * * "," token_type":"Bearer "," expiry_date":1593865140000," refresh _ token ":" jwt-placeholder " }

listFolderInGoogleDrive()被调用

已调用CreateFolderInGogleDrive()

错误:需要登录

我想,我没有使用令牌认证。请帮助我用Node.js代码来使用这个令牌来验证服务帐户。

共有1个答案

慕容耘豪
2023-03-14

我想修改以下修改。

    < Li > At < code > exports . handler = async(req,res) =
  • 但在这种情况下,我想建议将jwtClient包含在驱动器中,如google.drive({version:"v3", auth: jwtClient})

当上述要点反映到您的脚本中时,它将变为如下。在这种情况下,将使用服务私有密钥列表文件夹在谷歌驱动器和在谷歌驱动器中创建文件夹的功能被修改。

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);
      }
    }
  );
}
    < li >在此修改中,它假定您已经能够通过您的服务帐户使用Drive API获取和放置Google Drive的值。请小心这个。

如果要检索手动创建的文件的文件列表,请按如下方式修改范围。

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

>

  • 关于https://www.googleapis.com/auth/drive.file的范围,官方文件是这样说的。

    每个文件访问应用程序创建或打开的文件。文件授权是在每个用户的基础上授予的,当用户取消对应用程序的授权时,文件授权将被撤销。

    此外,如果您只想检索12CCq1GGoTyDW_Ox09TZf5BDgaPAjB0AR的共享文件夹的文件列表,请修改如下。

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

  •  类似资料:
    • 在Android>Sample app>Trivial Drive中,当运行应用程序时,我在执行IAP时得到以下信息: 我在手机上用测试帐户(即我在开发人员控制台中指定的测试电子邮件地址)切换到了一个单独的帐户,并遵循了以下所有步骤: https://android.stackExchange.com/questions/20369/geting-authentication-is-require

    • 我正试图从Python脚本中获得一个服务帐户来在Google Cloud Storage中创建Blob,但我遇到了凭据问题。 如果我将环境变量设置为 然后重新运行脚本。但是,我希望它在创建帐户的脚本的一个实例中运行,并继续在桶中创建必要的文件。如果我知道我的json凭据文件在哪里,我如何访问my_bucket。

    • 我正在调查AWS/Google云基础架构系统是否可以混合,我的要求之一是从一个系统到另一个系统的安全和简单的身份验证。目前,我需要从一个Google Cloud VM实例连接到一个受限的AWS S3 bucket。 我的问题通常是:有没有办法做到这一点,什么是最好的方法。我相信每个人都希望有机会使用多个云提供商为他们的基础设施提供高安全性、易用性和维护性。 经过一些研究,我发现唯一可能的方法是通过

    • 我已经在Google cloud中创建了服务帐户,但我无法使用该帐户登录或执行其他操作。请帮帮我。 我需要在管理控制台中执行操作,我需要以G Suite域的超级管理员身份登录,也启用了Gsuite域范围的委派,但在尝试访问/登录服务帐户时仍然出错。 服务帐户登录错误

    • 下午好! 我有麻烦访问谷歌团队驱动器。 我需要创建文件夹并从本地存储上传文件,所有这些都应该由我的应用程序完成。 目前,我已经学会了连接到我的个人谷歌硬盘,并在那里上传文件。我的个人存储连接代码: 告诉我,我如何连接到java中的Google Team Drive并在那里上传文件?谢谢:)

    • 我正在尝试使用服务帐户访问目录API(https://developers.google.com/admin-sdk/Directory/v1/reference/users/list)。最简单的任务是列出组织中的用户。通过OAuth2.0 PlayGorund测试,这在我的用户帐户中运行良好。但我需要使用服务帐户。我正在阅读关于双腿OAuth(https://developers.google.