【问题标题】:C# uploading file to google drive using service authenticationC#使用服务身份验证将文件上传到谷歌驱动器
【发布时间】:2019-12-04 23:49:49
【问题描述】:

我正在尝试将文件上传到我自己的谷歌驱动器。 我所做的是 1.在谷歌驱动器上创建项目 2.为服务帐户创建凭据 3.为一个用户创建安全json,并赋予用户作为所有者的权限 现在使用服务为用户提供的电子邮件和下载的 json 文件,尝试上传文件/创建文件夹。 没有错误,我正在取回文件 ID。

但是,当我在我的驱动器上检查它时,我没有看到上传的文件。 这是我的代码:

using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v2;
using Google.Apis.Drive.v2.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Google.Apis.Auth;
public void GetService()
        {
            string filename = "dheerajsecudata.json";
            string email = "dheeraj-588@secudata.iam.gserviceaccount.com";
            var service = AuthenticateServiceAccount(email, filename);
            CreateFolder("BlahBlah", service);
            var fileMetadata = new Google.Apis.Drive.v2.Data.File()
            {
                Title = "BrainData/bpl1.jpg"
            };
            FilesResource.InsertMediaUpload request;
            using (var stream = new System.IO.FileStream(@"D:/bpl1.jpg",
                                    System.IO.FileMode.Open))
            {
                request = service.Files.Insert(
                    fileMetadata, stream, "image/jpeg");
                request.Fields = "id";
                request.Upload();
            }
            var file = request.ResponseBody;
            Console.WriteLine("File ID: " + file.Id);//Getting ID but no folder / files on drive
        }
        private static void CreateFolder(string folderName, DriveService service)
        {
            var fileMetadata = new Google.Apis.Drive.v2.Data.File()
            {
                Title = folderName,
                MimeType = "application/vnd.google-apps.folder"
            };
            var request = service.Files.Insert(fileMetadata);
            request.Fields = "id";
            var file = request.Execute();
            Console.WriteLine("Folder ID: " + file.Id);

        }
        public static DriveService AuthenticateServiceAccount(string serviceAccountEmail, string serviceAccountCredentialFilePath)
        {
            try
            {
                if (string.IsNullOrEmpty(serviceAccountCredentialFilePath))
                    throw new Exception("Path to the service account credentials file is required.");
                if (!System.IO.File.Exists(serviceAccountCredentialFilePath))
                    throw new Exception("The service account credentials file does not exist at: " + serviceAccountCredentialFilePath);
                if (string.IsNullOrEmpty(serviceAccountEmail))
                    throw new Exception("ServiceAccountEmail is required.");

                // These are the scopes of permissions you need. It is best to request only what you need and not all of them
                //string[] scopes = new string[] { AnalyticsReportingService.Scope.Analytics };             // View your Google Analytics data
                string[] scopes = {  DriveService.Scope.Drive, DriveService.Scope.DriveFile };

                // For Json file
                if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".json")
                {
                    GoogleCredential credential;
                    using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
                    {
                        credential = GoogleCredential.FromStream(stream)
                             .CreateScoped(scopes);
                    }

                    // Create the  Analytics service.
                    return new DriveService(new BaseClientService.Initializer()
                    {
                        HttpClientInitializer = credential,
                        ApplicationName = "Drive Service account Authentication Sample",
                    });
                }

                else
                {
                    throw new Exception("Unsupported Service accounts credentials.");
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("Create service account DriveService failed" + ex.Message);
                throw new Exception("CreateServiceAccountDriveFailed", ex);
            }
        }

【问题讨论】:

  • 我已经尝试过使用 .p12 文件。没运气。我正在返回 fileid 但驱动器上没有文件。

标签: c# google-drive-api


【解决方案1】:
  • 如果您通过服务帐户创建文件夹,该文件夹将创建在您无权访问的服务帐户驱动器上
  • 要解决此问题,您需要设置impersonation
  • 换句话说,您需要设置服务帐户,使其代表您(或其他域用户)而不是代表自己进行操作
  • 在这种情况下,将在服务帐户模拟的用户的驱动器上创建文件夹
  • 要设置模拟,您需要通过管理控制台授予服务帐号 grant G Suite domain-wide authority
  • 在您的代码中,您需要设置一个主题(要模拟的用户的电子邮件)
  • Google documentation 提供了用于在 Java、Python 和 HTTP/REST 中委派域范围权限的示例代码
  • 对于 C#,您可以找到 sample code snippets 例如在stackoverflow上

【讨论】:

  • 谢谢!!但是对于没有域的小型项目,它不会起作用。就小型项目而言,获得域名是一项昂贵的事情。我通过授予许可找到了解决方案。现在它工作得很好。但是我无法删除我之前在测试时创建的文件和文件夹。没问题,我可以删除项目并新建一个!!
  • 很高兴您找到了解决方案!但是,即使你没有域,相信你也可以让服务帐号冒充你?
  • 是的,我能做到。现在我还有一个问题要解决!!我可以删除文件但无法删除文件夹。服务帐户需要什么权限才能删除文件夹?我授予了 OWNER 权限,并且能够使用 service.File.Delete(id) 删除文件。但同样不适用于文件夹
  • 您是否也将文件夹的所有者权限授予服务帐户?
猜你喜欢
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-07
  • 1970-01-01
  • 2019-11-10
相关资源
最近更新 更多