【问题标题】:"Forbidden" error uploading to Google Drive via API通过 API 上传到 Google Drive 时出现“禁止”错误
【发布时间】:2016-04-22 21:13:58
【问题描述】:

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

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

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

附加信息:Google.Apis.Requests.RequestError

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

我已经按照“快速入门”教程以及此处的其他类似问题进行了操作,但我看不出我还需要做什么。这是我上传文件的示例代码;我需要在我的代码或 Google Drive 帐户本身中添加/更改什么,以允许上传文件和创建文件夹?

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

【问题讨论】:

  • 请添加 UploadSingleFile 的代码
  • @DaImTo: 代码已经存在了吗?
  • 哎呀抱歉滚动条:/

标签: c# google-drive-api


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    问题可能是您请求的范围

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

    【讨论】:

    • 害怕 - 即使将我的 string[] Scopes 更改为 DriveService.Scope.Drive(而不是 .Drive.DriveFiles),我仍然得到 403 :(
    • 您是否更改了“用户”以强制其请求新范围?
    • 我只是用我通常使用的代码对其进行了测试。它对我有用,我看不出这和你使用的代码有什么区别。
    • 您是否必须在 Google 云端硬盘方面做任何事情来明确授予您的应用程序权限?
    • 不,它使用 Oauth2 会授予用户驱动器帐户的权限。只要您的项目在 Google 开发者控制台上设置并设置为访问驱动器,它就应该可以在不接触用户驱动器帐户的情况下工作。
    猜你喜欢
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 2016-10-06
    • 1970-01-01
    • 2021-02-11
    相关资源
    最近更新 更多