使用服务帐户身份验证访问Google日历API

8
4个回答

9
我很好奇为什么您第一次尝试使用服务账户教程时失败了。出了什么问题?有错误吗?
请记住,服务账户不是您本人。服务账户拥有自己的Google日历帐户,因此如果您尝试读取自己的“个人日历”,它将无法工作。您需要与服务账户共享您的个人日历。
这里是另一个示例,使用Json服务账户密钥文件
string[] scopes = new string[] { CalendarService.Scope.Calendar };
GoogleCredential credential;
using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
{
    credential = GoogleCredential.FromStream(stream)
                     .CreateScoped(scopes);
}

// Create the Calendar service.
var service = new CalendarService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = "Calendar Authentication Sample",
});

1
这篇文章(以及你的博客帖子)对我非常有帮助。终于通过使用服务帐户使我的应用程序向Google日历API进行了身份验证。谢谢! - dybzon
将服务账户的电子邮件地址与其它用户一样分享您的日历。在此过程中请注意日历ID。这样,它就会获得预批准。 - Linda Lawton - DaImTo
是的,我正在这样做。我去了我的日历,点击“添加朋友的日历”,并输入了服务电子邮件。然后我收到了以下错误提示: 无法添加日历“mobile-armour-test-key@mobilearmourtest.iam.gserviceaccount.com” 您没有访问mobile-armour-test-key@mobilearmourtest.iam.gserviceaccount.com的日历权限。 - Jalal El-Shaer
1
一个重要的事情。现在仅仅与服务账户共享日历是不够的。您必须通过CalendarList.insert(calendarId)在服务账户中接受它。请参考链接 - dcdrns
1
将我的个人日历与服务账户共享正是我需要做的。谢谢@JalalEl-Shaer! - T. Webster
显示剩余5条评论

2

如果有任何人需要NodeJS解决方案,并需要使用特定用户的具有域代表权限的服务账户登录,以下是方法:

const auth = new google.auth.JWT({    // use JWT instead of GoogleAuth 
    subject: "me@mycompany.com",      // specify subject (user whose context you want to operate in)
    keyFile: "service-account-key.json",
    scopes: [
        "https://www.googleapis.com/auth/calendar.events",
        "https://www.googleapis.com/auth/calendar.readonly"
    ],
})

2
试试这个。首先创建服务帐户,该帐户可以在您的Google Dev控制台中找到。
有关实施的参考,请查看
DalmTo的博客文章,了解如何在此处使用服务帐户。
以下是代码片段:
var certificate = new X509Certificate2(keyFile, "notasecret", X509KeyStorageFlags.Exportable);
try{
   ServiceAccountCredential credential = new ServiceAccountCredential(
      new ServiceAccountCredential.Initializer(serviceAccountEmail)
      {
          Scopes = scopes
      }.FromCertificate(certificate));

   //Create the service.
   DriveService service = new DriveService(new BaseClientService.Initializer()
   {
      HttpClientInitializer = credential,
      ApplicationName = "Drive API Sample"
   });
   return service;
}
catch (Exception ex)
{
    Console.WriteLine(ex.InnerException);
    return null;
}

1
访问此链接可获取完整的工作项目,其中包含使用Google服务帐户进行身份验证以及向Google日历插入事件的方法。您只需要更改您的JSON私钥和凭据即可。 https://github.com/CodeForget/Google-Service-Account-Authentication 在此处可以找到JSON密钥文件认证以及P12认证的内容。

ServiceAccountAuthentication.cs

using Google.Apis.Calendar.v3;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Calendar.v3.Data;

namespace GoogleSamplecSharpSample.Calendarv3.Auth
{



    public static class ServiceAccountExample
    {

        /// <summary>
        /// Authenticating to Google calender using a Service account
        /// Documentation: https://developers.google.com/accounts/docs/OAuth2#serviceaccount
        /// </summary>
        /// Both param pass from webform1.aspx page on page load
        /// <param name="serviceAccountEmail">From Google Developer console https://console.developers.google.com/projectselector/iam-admin/serviceaccounts </param>
        /// <param name="serviceAccountCredentialFilePath">Location of the .p12 or Json Service account key file downloaded from Google Developer console https://console.developers.google.com/projectselector/iam-admin/serviceaccounts </param>
        /// <returns>AnalyticsService used to make requests against the Analytics API</returns>

        public static CalendarService AuthenticateServiceAccount(string serviceAccountEmail, string serviceAccountCredentialFilePath, string[] scopes)
        {
            try
            {
                if (string.IsNullOrEmpty(serviceAccountCredentialFilePath))
                    throw new Exception("Path to the service account credentials file is required.");
                if (!File.Exists(serviceAccountCredentialFilePath))
                    throw new Exception("The service account credentials file does not exist at: " + serviceAccountCredentialFilePath);
                if (string.IsNullOrEmpty(serviceAccountEmail))
                    throw new Exception("ServiceAccountEmail is required.");

                // For Json file
                if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".json")
                {
                    GoogleCredential credential;
                    //using(FileStream stream = File.Open(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read, FileShare.None))


                    using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
                    {
                        credential = GoogleCredential.FromStream(stream)
                             .CreateScoped(scopes).CreateWithUser("xyz@gmail.com");//put a email address from which you want to send calendar its like (calendar by xyz user )
                    }

                    // Create the  Calendar service.
                    return new CalendarService(new BaseClientService.Initializer()
                    {
                        HttpClientInitializer = credential,
                        ApplicationName = "Calendar_Appointment event Using Service Account Authentication",
                    });
                }
                else if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".p12")
                {   // If its a P12 file

                    var certificate = new X509Certificate2(serviceAccountCredentialFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
                    var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
                    {
                        Scopes = scopes
                    }.FromCertificate(certificate));

                    // Create the  Calendar service.
                    return new CalendarService(new BaseClientService.Initializer()
                    {
                        HttpClientInitializer = credential,
                        ApplicationName = "Calendar_Appointment event Using Service Account Authentication",

                    });
                }
                else
                {
                    throw new Exception("Something Wrong With Service accounts credentials.");
                }

            }
            catch (Exception ex)
            {                
                throw new Exception("Create_Service_Account_Calendar_Failed", ex);
            }
        }


    }
}

添加webform.aspx并将以下代码放入webform.aspx.cs中

using System;
using Google.Apis.Calendar.v3;
using GoogleSamplecSharpSample.Calendarv3.Auth;
using Google.Apis.Calendar.v3.Data;

namespace CalendarServerToServerApi
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        // create event which you want to set using service account authentication 
        Event myEvent = new Event
        {
            Summary = "Visa Counselling",
            Location = "Gurgaon sector 57",
            Start = new EventDateTime()
            {
                DateTime = new DateTime(2017, 10, 4, 2, 0, 0),
                TimeZone = "(GMT+05:30) India Standard Time"
            },
            End = new EventDateTime()
            {
                DateTime = new DateTime(2017, 10, 4, 2, 30, 0),
                TimeZone = "(GMT+05:30) India Standard Time"
            }
            //,
            // Recurrence = new String[] {
            //"RRULE:FREQ=WEEKLY;BYDAY=MO"
            //}
            //,
            // Attendees = new List<EventAttendee>()
            // {
            // new EventAttendee() { Email = "Srivastava998@gmail.com" }
            //}
        };

        protected void Page_Load(object sender, EventArgs e)
        {

        }


        public void Authenticate(object o, EventArgs e)
        {
            string[] scopes = new string[] {
     CalendarService.Scope.Calendar //, // Manage your calendars
    //CalendarService.Scope.CalendarReadonly // View your Calendars
 };
            string cal_user = "calenderID@gamil.com"; //your CalendarID On which you want to put events
            //you get your calender id "https://calendar.google.com/calendar"
            //go to setting >>calenders tab >> select calendar >>Under calender Detailes at Calendar Address:

            string filePath = Server.MapPath("~/Key/key.json");
            var service = ServiceAccountExample.AuthenticateServiceAccount("xyz@projectName.iam.gserviceaccount.com", filePath, scopes);
            //"xyz@projectName.iam.gserviceaccount.com" this is your service account email id replace with your service account emailID you got it .
            //when you create service account https://console.developers.google.com/projectselector/iam-admin/serviceaccounts

            insert(service, cal_user, myEvent);

        }



        public static Event insert(CalendarService service, string id, Event myEvent)
        {
            try
            {
                return service.Events.Insert(myEvent, id).Execute();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }


    }
}

你知道如何在普通的HTTP身份验证或日历API调用中实现用户上下文.CreateWithUser("xyz@gmail.com")吗?(或在NodeJS库中) - Arash Motamedi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接