通过API上传到Google云端硬盘时出现“禁止”错误

本文关键字:禁止 错误 硬盘 API 云端 Google 通过 | 更新日期: 2023-09-27 18:30:46

我一直在使用.NET Google Drive API,我可以通过API成功连接,验证并获取文件列表(我们的Google云端硬盘帐户中已经有数千个文件,直接通过网络上传)。

但是,我在尝试写入数据时遇到两个非常相似的错误:如果我尝试上传测试文件 ( test.txt ),我会收到 403"禁止"错误。尝试创建新文件夹会给我一个类似的错误:

抛出的异常:Google.Apis 中的"Google.GoogleApiException.dll

其他信息:Google.Apis.Requests.RequestError

权限不足 [403] 位置[ - ] 原因[权限不足] 域[全局]

我已经按照"快速入门"教程和此处的其他类似问题进行操作,但我不知道我还需要做什么。这是我上传文件的示例代码;我需要在代码或 Google 云端硬盘帐户中添加/更改哪些内容才能上传文件和创建文件夹?

 class GDriveTest
{
    static string[] Scopes = { DriveService.Scope.Drive,DriveService.Scope.DriveFile };
    static string ApplicationName = "Drive API .NET Quickstart";
    static void Main(string[] args)
    {
        UserCredential credential;
        using (var stream =
            new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
        {
            string credPath = System.Environment.GetFolderPath(
                System.Environment.SpecialFolder.Personal);
            credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart");
            credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                Scopes,
                "user",
                CancellationToken.None,
                new FileDataStore(credPath, true)).Result;
            Console.WriteLine("Credential file saved to: " + credPath);
        }
        // Create Drive API service.
        var service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = ApplicationName,
        });
        UploadSingleFile(service);
    }
    private static void UploadSingleFile(DriveService service)
    {
        File body = new File();
        body.Title = "My document";
        body.Description = "A test document";
        body.MimeType = "text/plain";
        byte[] byteArray = System.IO.File.ReadAllBytes("test.txt");
        System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
        FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, "text/plain");
        request.Upload();
        File file = request.ResponseBody;
        Console.WriteLine("File id: " + file.Id);
        Console.ReadLine();
    }
}

通过API上传到Google云端硬盘时出现“禁止”错误

问题可能是您请求的范围

DriveService.Scope.DriveFile,   // view and manage files created by this app

尝试

DriveService.Scope.Drive,  // view and manage your files and documents

我的代码:

 /// <summary>
        /// Authenticate to Google Using Oauth2
        /// Documentation https://developers.google.com/accounts/docs/OAuth2
        /// </summary>
        /// <param name="clientId">From Google Developer console https://console.developers.google.com</param>
        /// <param name="clientSecret">From Google Developer console https://console.developers.google.com</param>
        /// <param name="userName">The user to authorize.</param>
        /// <returns>a valid DriveService</returns>
        public static DriveService AuthenticateOauth(string clientId, string clientSecret, string userName)
        {
            if (string.IsNullOrEmpty(clientId))
                throw new Exception("clientId is required.");
            if (string.IsNullOrEmpty(clientSecret))
                throw new Exception("clientSecret is required.");
            if (string.IsNullOrEmpty(userName))
                throw new Exception("userName is required for datastore.");

            string[] scopes = new string[] { DriveService.Scope.Drive};
            try
            {
                string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                credPath = Path.Combine(credPath, ".credentials/Drive");
                // here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
                UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
                                                                                             , scopes
                                                                                             , userName
                                                                                             , CancellationToken.None
                                                                                             , new FileDataStore(credPath, true)).Result;
                var service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive Authentication Sample",
                });
                return service;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException);
                throw ex;
            }
        }
/// <summary>
        /// Insert a new file.
        /// Documentation: https://developers.google.com/drive//v2/files/insert
        /// </summary>
        /// <param name="service">Valid authentcated DriveService</param>
        /// <param name="body">Valid File Body</param>
        /// <returns>File </returns>
        public static File Insert(DriveService service, File body)
        {
            //Note Genrate Argument Exception (https://msdn.microsoft.com/en-us/library/system.argumentexception(loband).aspx)
            try
            {  
            return          service.Files.Insert(body).Execute();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Request Failed " + ex.Message);
                throw ex;
            }
         }
  private static string GetMimeType(string fileName)
        {
            string mimeType = "application/unknown";
            string ext = System.IO.Path.GetExtension(fileName).ToLower();
            Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
            if (regKey != null && regKey.GetValue("Content Type") != null)
                mimeType = regKey.GetValue("Content Type").ToString();
            return mimeType;
        }

执行

var driveService = StandardGoogleAuth.AuthenticateOauth("xxxxx.apps.googleusercontent.com", "uxpj6hx1H2N5BFqdnaNhIbie", "user");
                var uploadfileName = @"C:'Temp'test.txt";
               File body = new File();
                body.Title = System.IO.Path.GetFileName(uploadfileName);
                body.Description = "File uploaded by Diamto Drive Sample";
                body.MimeType =  GetMimeType(uploadfileName);
                body.Parents = new List<ParentReference>() { new ParentReference() { Id = "root" } };
                // File's content.
                byte[] byteArray = System.IO.File.ReadAllBytes(uploadfileName);
                System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
             var result = FilesSample.Insert(driveService,body);

修改范围不会自动更新到 TOKENRESPONSE 用户文件中。您必须重新生成该文件。

搜索"drive-dotnet-quickstart.json"并从中删除"Google.Apis.Auth.OAuth2.Responses.TokenResponse-user"。然后运行代码以重新生成该文件。