我最近尝试遵循此指南: 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)。
预先感谢您的帮助。