DEV Community

Jonathan Eccker for DealerOn Dev

Posted on

Server To Server Google Api Credentials Without a Json File in .Net

All Google documentation indicates that you need a special JSON file for configuration of google calls. This breaks the standard configuration pattern that .Net uses (IConfiguration abstraction/layers, IOptions injection, etc.)

After poking around at the classes available in the Nuget Package, I was able to hook this all up for server side calls in a very simple way.

To cut to the chase, here's the code, note that this is code for interacting with the Calendar API but it'll be similar for other API services.

public sealed class CalendarEventRepository : ICalendarEventRepository
{
  private readonly GoogleConfiguration _configuration;
  public CalendarEventRepository(IOptions<GoogleConfiguration> options)
  {
    _configuration = options.Value;
  }
  public async Task<IEnumerable<CalendarEvent>> GetUpcomingCalendarEvents(CancellationToken cancellationToken)
  {
    var credentialJson = new
    {
      type = "service_account",
      project_id = _configuration.ProjectId,
      private_key_id = _configuration.PrivateKeyId,
      private_key = _configuration.PrivateKey.Replace("\\n","\n"),
      client_email = _configuration.ClientEmail,
      client_id = _configuration.ClientId,
      auth_uri = "https://accounts.google.com/o/oauth2/auth",
      token_uri = "https://oauth2.googleapis.com/token",
      auth_provider_x509_cert_url = "https://www.googleapis.com/oauth2/v1/certs",
      client_x509_cert_url = "https://www.googleapis.com/robot/v1/metadata/x509/" + Uri.EscapeUriString(_configuration.ClientEmail)
    };
    var credentials = GoogleCredential.FromJson(JsonConvert.SerializeObject(credentialJson)).CreateScoped(new[] { CalendarService.Scope.Calendar });

    var service = new CalendarService(new BaseClientService.Initializer()
    {
      ApplicationName = "<Your Application Name>",
      HttpClientInitializer = credentials
    });
    var eventRequest = service.Events.List(_configuration.CalendarId);
    eventRequest.MaxResults = 10;
    var result = await eventRequest.ExecuteAsync();
    return result.Items.Select(i => new CalendarEvent(HashToGuid(i.Id), i.Summary, DateTimeOffset.Parse(i.Start.Date), DateTimeOffset.Parse(i.End.Date))).ToArray();
  }

  private Guid HashToGuid(string input)
  {
    using (MD5 md5 = MD5.Create())
    {
      byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(input));
      return new Guid(hash);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The important points to note are:

  • You can use GoogleCredentials.FromJson and assign that to HttpClientInitializer
  • I did a .Replace("\\n","\n") on the private key because many configuration providers don't support new lines
  • The variables you'll need to add into configuration are: ProjectId, PrivateKeyId, PrivateKey, ClientId, ClientEmail (and CalendarId if you're using calendars)
  • The Google Nuget Package I'm using here is Google.Apis.Calendar.v3, version 1.52.0.2312

Discussion (0)