Google Drive Api – 带有entity framework的自定义IDataStore

我实现了我的自定义IDataStore以便我可以在我的数据库上存储最终用户令牌而不是默认实现,该实现保存在%AppData%中的FileSystem上

 public class GoogleIDataStore : IDataStore { ... public Task GetAsync(string key) { TaskCompletionSource tcs = new TaskCompletionSource(); var user = repository.GetUser(key.Replace("oauth_", "")); var credentials = repository.GetCredentials(user.UserId); if (key.StartsWith("oauth") || credentials == null) { tcs.SetResult(default(T)); } else { var JsonData = Newtonsoft.Json.JsonConvert.SerializeObject(Map(credentials)); tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize(JsonData)); } return tcs.Task; } } 

调节器

 public async Task AuthorizeDrive(CancellationToken cancellationToken) { var result = await new AuthorizationCodeMvcApp(this, new GoogleAppFlowMetadata()). AuthorizeAsync(cancellationToken); if (result.Credential == null) return new RedirectResult(result.RedirectUri); var driveService = new DriveService(new BaseClientService.Initializer { HttpClientInitializer = result.Credential, ApplicationName = "My app" }); //Example how to access drive files var listReq = driveService.Files.List(); listReq.Fields = "items/title,items/id,items/createdDate,items/downloadUrl,items/exportLinks"; var list = listReq.Execute(); return RedirectToAction("Index", "Home"); } 

问题发生在重定向事件上。 在第一次重定向后,它工作正常。

我发现重定向事件有些不同。 在重定向事件中, T不是令牌响应,而是字符串。 此外,密钥的前缀是“oauth_”。

所以我假设我应该在重定向上返回不同的结果,但我不知道要返回什么。

我得到的错误是: Google.Apis.Auth.OAuth2.Responses.TokenResponseException:错误:“状态无效”,描述:“”,Uri:“”

Google源代码参考 https://code.google.com/p/google-api-dotnet-client/source/browse/Src/GoogleApis.DotNet4/Apis/Util/Store/FileDataStore.cs?r=eb702f917c0e18fc960d077af132d0d83bcd6a88

https://code.google.com/p/google-api-dotnet-client/source/browse/Src/GoogleApis.Auth/OAuth2/Web/AuthWebUtility.cs?r=eb702f917c0e18fc960d077af132d0d83bcd6a88

谢谢你的帮助

我不确定你为什么不工作,但这是我使用的代码的副本。 完整的类可以在DatabaseDatastore.cs中找到

 ///  /// Returns the stored value for the given key or null if the matching file ( /// in  doesn't exist. ///  /// The type to retrieve /// The key to retrieve from the data store /// The stored object public Task GetAsync(string key) { //Key is the user string sent with AuthorizeAsync if (string.IsNullOrEmpty(key)) { throw new ArgumentException("Key MUST have a value"); } TaskCompletionSource tcs = new TaskCompletionSource(); // Note: create a method for opening the connection. SqlConnection myConnection = new SqlConnection("user id=" + LoginName + ";" + @"password=" + PassWord + ";server=" + ServerName + ";" + "Trusted_Connection=yes;" + "database=" + DatabaseName + "; " + "connection timeout=30"); myConnection.Open(); // Try and find the Row in the DB. using (SqlCommand command = new SqlCommand("select RefreshToken from GoogleUser where UserName = @username;", myConnection)) { command.Parameters.AddWithValue("@username", key); string RefreshToken = null; SqlDataReader myReader = command.ExecuteReader(); while (myReader.Read()) { RefreshToken = myReader["RefreshToken"].ToString(); } if (RefreshToken == null) { // we don't have a record so we request it of the user. tcs.SetResult(default(T)); } else { try { // we have it we use that. tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize(RefreshToken)); } catch (Exception ex) { tcs.SetException(ex); } } } return tcs.Task; } 

API会在您的IDataStore存储(至少)两个值。 以下是从空IDataStore的角度看授权过程的样子(注意哪些行设置了一个值,哪些行得到了一个值):

 Getting IDataStore value: MyKey <= null Setting IDataStore value: oauth_MyKey => "http://localhost..." Setting IDataStore value: MyKey => {"access_token":"... Getting IDataStore value: oauth_MyKey <= "http://localhost..." Getting IDataStore value: MyKey <= {"access_token":"... 

首先,API尝试查找存储的access_token ,但数据存储中没有(只返回null ),API启动授权过程。 “oauth _...”键是API在此过程中需要的一些状态信息,通常在检索之前设置(根据我的经验)。

但是,如果您的IDataStore从未收到带有“oauth_ ..”键的值,因此无法返回任何内容,则只需返回null ,并且API应在需要时创建一个新值。