访问令牌已过期但我们无法刷新它的异常

时间:2016-11-23 12:59:55

标签: c# google-api google-oauth google-api-dotnet-client google-authentication

我正在尝试使用.NET API从Google云端硬盘下载文件。

    private UserCredential _credential;

    protected void Authorize()
    {
        var scopes = new[] {DriveService.Scope.DriveReadonly};

        using (var stream = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
        {
            var credentialPath = @"App_Data\credential";

            _credential =
                new UserCredential(new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = GoogleClientSecrets.Load(stream).Secrets,
                    Scopes = scopes
                }), Environment.UserName, new TokenResponse());

            // I tried both ways, both result the same exception
            //_credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, scopes, Environment.UserName, CancellationToken.None).Result;
        }
    }

    public Download SaveAsDownload(string fileId)
    {
        if(_credential == null)
            Authorize();

        var service = new DriveService(new BaseClientService.Initializer()
        {
            ApiKey = ApiKey,
            HttpClientInitializer = _credential
        });

        var getRequest = service.Files.Get(fileId);
        var file = getRequest.Execute(); // When I call this I get the exception

        return null;
    }

每次我尝试这样做时,我都会收到“访问令牌已过期,但我们无法刷新”异常。我找到的唯一答案是尝试其他方式的身份验证,但我尝试了两种方式,两者都导致相同的异常。 我试过了谷歌SDK的v2和v3版本。

1 个答案:

答案 0 :(得分:0)

请删除

  

ApiKey = ApiKey,

来自您的DriveService的

。当客户端库应该使用您的OAuth凭据时,您正在混淆尝试使用公共API密钥。

有几次在库Creating service with credentials and ApiKey

上发布了一个问题

更新也可能是您的代码的问题

我的驱动程序验证码:

    /// <summary>
    /// This method requests Authentcation from a user using Oauth2.  
    /// Credentials are stored in System.Environment.SpecialFolder.Personal
    /// Documentation https://developers.google.com/accounts/docs/OAuth2
    /// </summary>
    /// <param name="clientSecretJson">Path to the client secret json file from Google Developers console.</param>
    /// <param name="userName">Identifying string for the user who is being authentcated.</param>
    /// <returns>DriveService used to make requests against the Drive API</returns>
    public static DriveService AuthenticateOauth(string clientSecretJson, string userName)
    {
        try
        {
            if (string.IsNullOrEmpty(userName))
                throw new Exception("userName is required.");
            if (!File.Exists(clientSecretJson))
                throw new Exception("clientSecretJson file does not exist.");

            // 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[] {DriveService.Scope.DriveReadonly};           // Modify your Google Apps Script scripts' behavior
            UserCredential credential;
            using (var stream = new FileStream(clientSecretJson, FileMode.Open, FileAccess.Read))
            {
                string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                credPath = Path.Combine(credPath, ".credentials/apiName");

                // Requesting Authentication or loading previously stored authentication for userName
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
                                                                         scopes,
                                                                         userName,
                                                                         CancellationToken.None,
                                                                         new FileDataStore(credPath, true)).Result;
            }

            // Create Drive API service.
            return new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive Authentication Sample",
                });
        }
        catch (Exception ex)
        {
            Console.WriteLine("Create Oauth2 DriveService failed" + ex.Message);
            throw new Exception("CreateOauth2DriveFailed", ex);
        }
    }