【问题标题】:Google Drive. Refresh authorization token while a file is uploading谷歌云端硬盘。上传文件时刷新授权令牌
【发布时间】:2012-10-15 14:23:28
【问题描述】:

在将大文件上传到 Google 云端硬盘时,如何刷新授权令牌? 例如:当前授权令牌的过期时间为“06:00 AM”。文件上传从“05:15 AM”开始。因此,在“06:00 AM”应用程序由于授权令牌无效而获得异常。

我已尝试使用以下源代码解决此问题,但它不起作用。

/// <summary>
/// Uploads a file with a specified path.
/// </summary>
/// <param name="startFolder">The start folder.</param>
/// <param name="path">The path of destination file.</param>
/// <param name="localFile">The local file to upload.</param>
/// <returns>The uploaded file.</returns>
private File GdUploadFile(File startFolder, string path, FileInfo localFile)
{
    if (startFolder == null)
    {
        throw new ArgumentNullException("startFolder");
    }

    if (localFile == null)
    {
        throw new ArgumentNullException("localFile");
    }

    if (!localFile.Exists)
    {
        throw new FileNotFoundException("File not found", localFile.FullName);
    }

    var config = GetConfiguration();

    if (config.TraceLog)
    {
        Destination.Logger.LogDebug(string.Format("{0} \tUpload file \"{1}\" to \"{2}\"", Destination.Name, localFile.FullName, path));
    }

    string pathToFile = string.IsNullOrEmpty(path) ? localFile.Name : path;

    string remotePath = ExtractFilePath(pathToFile);
    var fileFolder = GdCreateFolderByPath(startFolder, remotePath);
    var fileName = ExtractFileName(pathToFile);

    DriveService service = GetDriveService();

    var body = new File
                   {
                       Title = fileName,
                       Description = "My File",
                       MimeType = BackupFileMimeType,
                       Kind = DriveFileKindType,
                       OriginalFilename = fileName,
                       FileExtension = localFile.Extension,
                       Parents = new List<ParentReference>
                                     {
                                         new ParentReference
                                             {
                                                 ETag = fileFolder.ETag,
                                                 Id = fileFolder.Id,
                                                 Kind = fileFolder.Kind
                                             }
                                     }
                   };

    FilesResource.InsertMediaUpload request;
    var source = new MediaFileSource(localFile.FullName, BackupFileMimeType);

    using (var fileStream = source.GetDataStream())
    {
        if (config.TraceLog)
        {
            Destination.Logger.LogDebug(string.Format("{0} \tUploading \"{1}\"...", Destination.Name, localFile.FullName));
        }

        request = service.Files.Insert(body, fileStream, body.MimeType);

        if (config.TraceLog)
        {
            int postedPercent = 0;

            request.ProgressChanged += p =>
                                           {
                                               var currentPercent = (int) (p.BytesSent/(double) source.ContentLength*100);

                                               if (currentPercent != postedPercent)
                                               {
                                                   string msg = string.Format("{0} \tPosted {1}% ({2} bytes)", Destination.Name,
                                                                              currentPercent, p.BytesSent);
                                                   Destination.Logger.LogDebug(msg);
                                                   postedPercent = currentPercent;
                                               }
                                           };
        }

        var connection = Destination.Connection as GoogleDriveDestinationConnection;
        Debug.Assert(connection != null, "connection != null");

        request.ProgressChanged += p =>
                                       {
                                           bool refreshAuth = connection.ForceRefreshAuthorization();
                                           var auth =
                                               request.Authenticator as
                                               Google.Apis.Authentication.OAuth2.OAuth2Authenticator<NativeApplicationClient>;

                                           if (auth != null && auth.State != null && refreshAuth)
                                           {
                                               var state = connection.AuthorizationState;
                                               auth.State.AccessToken = state.AccessToken;
                                               auth.State.AccessTokenExpirationUtc = state.AccessTokenExpirationUtc;
                                               auth.State.AccessTokenIssueDateUtc = state.AccessTokenIssueDateUtc;
                                               auth.State.Callback = state.Callback;
                                               auth.State.RefreshToken = state.RefreshToken;
                                               auth.State.SaveChanges();

                                               if (config.TraceLog)
                                               {
                                                   Destination.Logger.LogDebug("Authorization state for the upload request is updated");
                                               }

                                           }
                                       };

        request.ChunkSize = ChunkSize;
        request.Upload();

        if (config.TraceLog)
        {
            Destination.Logger.LogDebug(string.Format("{0} \t\"{1}\" uploaded", Destination.Name, localFile.FullName));
        }
    }

    return request.ResponseBody;
}

【问题讨论】:

  • 如果令牌将在一小时内到期,请在开始文件上传过程之前刷新令牌。
  • 是的,这是个好主意。我打算通过这种方式来解决这个问题。但在这种情况下,如果时间超过一小时,用户将无法上传文件(上传大文件,互联网连接速度慢)。

标签: c# google-api google-drive-api


【解决方案1】:

考虑进行可恢复上传 (https://developers.google.com/drive/manage-uploads#resumable)。需要时刷新令牌,然后从上次中断的地方继续上传。

【讨论】:

【解决方案2】:

我无法为无效授权令牌问题找到令人满意的解决方案。 因此,我创建了自己的开源轻量级库,用于处理 Google Drive 上的文件。该库直接调用所有 REST 函数,并完全控制上传或下载过程。它通过每小时刷新授权令牌来解决问题。该库目前在我公司的 Sql Server 备份产品上千次安装中使用,非常稳定,成功解决了这个问题。您可以从这里获取源代码和示例:https://github.com/AlexeyVlg/Pranas.Net.Clouds

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多