尝试使用谷歌的点网库和服务帐户进行简单的谷歌驱动器API测试

时间:2013-08-06 12:20:49

标签: google-api-dotnet-client google-drive-realtime-api

我将下面的示例代码放在一起,使用谷歌的dot net google api客户端库的示例附带的一些帮助代码。

问题:即使我将一个文件信息上传到拥有此服务帐户的Gooogle帐户,它也不会列出任何文件信息。

当我尝试使用oauth授权执行同样的操作时,我得到了预期的结果(我在此页面上执行了此操作:https://developers.google.com/drive/v2/reference/files/list)。

可能存在范围问题或其他问题;有任何想法吗?

我尝试记录所有http请求和响应已完全失败。谷歌客户端库似乎已经基于per-api登录,我看不到任何谷歌驱动器。当我尝试使用log4net和dotnetopenauth时也没有做任何事情(google的客户端库使用dot net open auth)。

以下是代码:

using System;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using Google.Apis.Drive.v2;
using Google.Apis.Util;
using Google.Apis.Services;

namespace Drive.ServiceAccount
{
    class Program
    {

        static Program()
        {
//
            //ApplicationContext.RegisterLogger(new Log4NetLogger());
            log4net.Config.XmlConfigurator.Configure();          
        }

        private const string SERVICE_ACCOUNT_EMAIL = "<blablalba>@developer.gserviceaccount.com";
        private const string SERVICE_ACCOUNT_PKCS12_FILE_PATH = @"<blablalba>-privatekey.p12";

        /// <summary>
        /// Build a Drive service object authorized with the service account.
        /// </summary>
        /// <returns>Drive service object.</returns>
        static DriveService BuildService()
        {
            X509Certificate2 certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret",
                X509KeyStorageFlags.Exportable);

            var _client = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
            {
                ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
                Scope = DriveService.Scopes.Drive.GetStringValue(),
            };
            var auth = new OAuth2Authenticator<AssertionFlowClient>(_client, AssertionFlowClient.GetState);

            var service = new DriveService(new BaseClientService.Initializer()
            {
                Authenticator = auth,
                ApplicationName = "Drive API Sample",
            });

            return service;
        }

        static void Main(string[] args)
        {
            var _driveService = BuildService();

            var _files = _driveService.Files.List().Execute();

            foreach (var _file in _files.Items)
            {
                Console.WriteLine(_file.Id);
            }

            Console.WriteLine("Done");

            Console.ReadLine();
        }

    }
}

感谢Robadob纠正了我对服务帐户的误解。这是一些工作代码(只是主要方法,其他一切如上):

static void Main(string[] args)
{

    String _newFileName = Guid.NewGuid().ToString() + ".xml";

    new XDocument( new XElement("root", new XElement("someNode", "someValue")))
        .Save(_newFileName);

    Console.WriteLine("New file saved locally with name {0}.", _newFileName);

    var _driveService = BuildService();

    // upload the file:

    //var uploadStream = 
    //    new System.IO.FileStream(_newFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);

    byte[] byteArray = System.IO.File.ReadAllBytes(_newFileName);
    MemoryStream _byteStream = new MemoryStream(byteArray);

    var insert = _driveService.Files.Insert(new Google.Apis.Drive.v2.Data.File
    {
        Title = _newFileName,
    }, _byteStream, "text/xml");

    Task _uploadTask = insert.UploadAsync();

    _uploadTask.ContinueWith(t => Console.WriteLine("Upload Task Completed"),TaskContinuationOptions.OnlyOnRanToCompletion);
    //

    try
    {
        _uploadTask.Wait();
    }
    catch (AggregateException _ex)
    {
        foreach (Exception ex in _ex.Flatten().InnerExceptions)
        {
            Console.WriteLine(ex.Message);
        }
    }

    Console.WriteLine("Reading files");

    var _files = _driveService.Files.List();


    foreach (var _file in _files.Execute().Items)
    {
        Console.WriteLine(_file.Id);
    }

    Console.WriteLine("Done");

    Console.ReadLine();
}

1 个答案:

答案 0 :(得分:0)

由于它是一个服务帐户我不相信它有自己的“Google云端硬盘”,因此存在服务帐户代表用户行事。

要“模拟”您要列出其文件的用户,您需要在生成访问令牌时传递prn参数;

如果您向下滚动到“其他声明”,可以在此处找到详细信息; https://developers.google.com/accounts/docs/OAuth2ServiceAccount#formingclaimset

好像您可以通过此设置用户;

        var _client = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
        {
            ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
            Scope = DriveService.Scopes.Drive.GetStringValue(),
            ServiceAccountUser = "Name@Company.com"
        };

如果您希望记录HTTP交互,我发现Fiddler比其他方法更容易设置。