API Календаря Google: свойство Credential всегда равно null - PullRequest
0 голосов
/ 22 мая 2019

Я недавно пытался следовать этому руководству: https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web_applications

После того, как я войду в систему, свойство Credential по-прежнему будет иметь значение null, и оно снова перенаправит меня на страницы входа и авторизации после того, как я только войду в систему и предоставлю авторизацию из учетной записи:

public async Task<ActionResult> Index(CancellationToken cancellationToken)
    {
        var authResult = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
            AuthorizeAsync(cancellationToken);

        if (authResult.Credential != null)
        {
            var service = new CalendarService(new BaseClientService.Initializer
            {
                HttpClientInitializer = authResult.Credential,
                ApplicationName = "Intranet - Google Calendar API Test"
            });

            const int MaxEventsPerCalendar = 20;
            const int MaxEventsOverall = 50;

            var calendars = await service.CalendarList.List().ExecuteAsync();

            var fetchTasks = new List<Task<Events>>(calendars.Items.Count);
            foreach (var calendar in calendars.Items)
            {
                var request = service.Events.List(calendar.Id);
                request.MaxResults = MaxEventsPerCalendar;
                request.SingleEvents = true;
                request.TimeMin = DateTime.Now;
                fetchTasks.Add(request.ExecuteAsync());
            }

            var fetchResults = await Task.WhenAll(fetchTasks);

            // Sort the events and put them in the model.
            var upcomingEvents = from result in fetchResults
                                 from evt in result.Items
                                 where evt.Start != null
                                 let date = evt.Start.DateTime.HasValue ?
                                     evt.Start.DateTime.Value.Date :
                                     DateTime.ParseExact(evt.Start.Date, "yyyy-MM-dd", null)
                                 let sortKey = evt.Start.DateTimeRaw ?? evt.Start.Date
                                 orderby sortKey
                                 select new { evt, date };

            var eventsByDate = from result in upcomingEvents.Take(MaxEventsOverall)
                               group result.evt by result.date into g
                               orderby g.Key
                               select g;

            var eventGroups = new List<CalendarEventGroup>();
            foreach (var grouping in eventsByDate)
            {
                eventGroups.Add(new CalendarEventGroup
                {
                    GroupTitle = grouping.Key.ToLongDateString(),
                    Events = grouping,
                });
            }

            return View(eventGroups);
        }
        else
        {
            return new RedirectResult(authResult.RedirectUri);
        }
    }

Я думаю, это может быть связано со свойством DataStore:

public class AppFlowMetadata : FlowMetadata
{
    private static readonly IAuthorizationCodeFlow flow =
        new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = new ClientSecrets
            {
                ClientId = "a_client_id",
                ClientSecret = "a_client_secret"
            },

            Scopes = new[] { CalendarService.Scope.Calendar },
            //Scopes = new[] { DriveService.Scope.Drive },

            //DataStore = new DataStore()
            //DataStore = new FileDataStore(GoogleWebAuthorizationBroker.Folder)
            DataStore = new FileDataStore("Calendar.Api.Auth.Store")
            //DataStore = new FileDataStore("Drive.Api.Auth.Store")
        });

    public override string GetUserId(Controller controller)
    {
        // In this sample we use the session to store the user identifiers.
        // That's not the best practice, because you should have a logic to identify
        // a user. You might want to use "OpenID Connect".
        // You can read more about the protocol in the following link:
        // https://developers.google.com/accounts/docs/OAuth2Login.
        var user = controller.Session["user"];
        if (user == null)
        {
            user = Guid.NewGuid();
            controller.Session["user"] = user;
        }

        return user.ToString();
    }

    public override string AuthCallback
    {
        get
        {
            return @"/Agenda/";
        }
    }

    public override IAuthorizationCodeFlow Flow
    {
        get { return flow; }
    }
}

Я попытался реализовать хранилище данных из примера, представленного на следующем веб-сайте (http://www.sparkhound.com/blog/google-oauth-integration-using-an-mvc-asp-net-app-1), но он все еще не работает:

public class DataStore : IDataStore
{
    public Task ClearAsync()
    {
        GoogleOauthTokenService.OauthToken = null;
        return Task.Delay(0);
    }

    public Task DeleteAsync<T>(string key)
    {
        GoogleOauthTokenService.OauthToken = null;
        return Task.Delay(0);
    }

    public Task<T> GetAsync<T>(string key)
    {
        var result = GoogleOauthTokenService.OauthToken;

        var value = result == null ? default(T) : NewtonsoftJsonSerializer.Instance.Deserialize<T>(result);

        //var value = result == null ? default(T) : NewtonsoftJsonSerializer.Instance.Deserialize<T>(result);

        return Task.FromResult<T>(value);
    }

    public Task StoreAsync<T>(string key, T value)
    {
        var jsonData = JsonConvert.SerializeObject(value);

        GoogleOauthTokenService.OauthToken = jsonData;
        // GoogleOauthTokenService.OauthToken = value.ToString();

        return Task.Delay(0);
    }
}

Когда вызывается StoreAsync (вызывается до того, как я вхожу в систему и предоставляю полномочия), параметры-значения выглядят так: http://localhost:58893/Agenda20394029. Затем при следующем вызове GetAsync (после входа в систему) происходит сбой приложения (ArgumentException: не удалось преобразовать или преобразовать из System.String в Google.Apis.Auth.OAuth2.Responses.TokenResponse).

Заранее спасибо за помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...