我使用的是最新版本的 Google .NET Client API (v1.81)。我正在尝试使用以下代码连接到日历服务
var calendarService = new CalendarService(new BaseClientService.Initializer
{
HttpClientInitializer = GetCredential(),
ApplicationName = "MyApp"
});
public UserCredential GetCredential()
{
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets { ClientId = _clientId, ClientSecret = _clientSecret },
new[] { CalendarService.Scope.Calendar }.ToList(), "user", CancellationToken.None,
new FileDataStore("Drive.Auth.Store")).Result;
return credential;
}
当我这样做时,它会打开一个新的浏览器窗口并要求我进行身份验证。我之前已经过身份验证,并且通过 FileDataStore 存储和检索 key 。
为什么它会要求我再次进行身份验证?问题是因为此代码需要在后台服务中运行,因此无法打开浏览器选项卡。
我现在遇到的另一个问题是,当我尝试授权它打开一个新的浏览器窗口时,我选择了我的凭据,但登录页面随后告诉我
“请求中的重定向 URI:http://localhost:51773/authorize/
与已注册的重定向 URI 不匹配”
为什么它尝试使用授权 url 而不是 AuthCallbackController。它还似乎随机更改重定向 uri 的端口号,使得无法注册。
最终的问题可能是,如果我有一个 Web 应用程序并且我希望用户通过网页使用他们的凭据登录,然后在以后的某个日期在服务器的后台任务中重用这些凭据,我该如何去那?我找不到任何相关的示例应用程序来展示如何操作。似乎 FileDataStore 不存储凭据,因此可以重复使用它们。我还实现了自己的 DataStore,将它们保存在数据库中,但似乎也不起作用。
进一步研究发现我需要 offline_access。我已经实现了与 Google Analytics OAuth with AccessType = Offline in C# 相同的方式但它仍然提示。如何重复使用 offline_access 刷新 token ?
最佳答案
您是对的,您需要创建自己的 Idatastore imp 实现。这将允许您将刷新 token 保存到数据库中并在以后使用。
这是一个非常粗略的例子
///
/// Saved data store that implements .
/// This Saved data store stores a StoredResponse object.
///
class SavedDataStore : IDataStore
{
public StoredResponse _storedResponse { get; set; }
///
/// Constructs Load previously saved StoredResponse.
///
///Stored response
public SavedDataStore(StoredResponse pResponse)
{
this._storedResponse = pResponse;
}
public SavedDataStore()
{
this._storedResponse = new StoredResponse();
}
///
/// Stores the given value. into storedResponse
/// .
///
///The type to store in the data store
///The key
///The value to store in the data store
public Task StoreAsync(string key, T value)
{
var serialized = NewtonsoftJsonSerializer.Instance.Serialize(value);
JObject jObject = JObject.Parse(serialized);
// storing access token
var test = jObject.SelectToken("access_token");
if (test != null)
{
this._storedResponse.access_token = (string)test;
}
// storing token type
test = jObject.SelectToken("token_type");
if (test != null)
{
this._storedResponse.token_type = (string)test;
}
test = jObject.SelectToken("expires_in");
if (test != null)
{
this._storedResponse.expires_in = (long?)test;
}
test = jObject.SelectToken("refresh_token");
if (test != null)
{
this._storedResponse.refresh_token = (string)test;
}
test = jObject.SelectToken("Issued");
if (test != null)
{
this._storedResponse.Issued = (string)test;
}
return TaskEx.Delay(0);
}
///
/// Deletes StoredResponse.
///
///The key to delete from the data store
public Task DeleteAsync(string key)
{
this._storedResponse = new StoredResponse();
return TaskEx.Delay(0);
}
///
/// Returns the stored value for_storedResponse
///The type to retrieve
///The key to retrieve from the data store
/// The stored object
public Task GetAsync(string key)
{
TaskCompletionSource tcs = new TaskCompletionSource();
try
{
string JsonData = Newtonsoft.Json.JsonConvert.SerializeObject(this._storedResponse);
tcs.SetResult(Google.Apis.Json.NewtonsoftJsonSerializer.Instance.Deserialize(JsonData));
}
catch (Exception ex)
{
tcs.SetException(ex);
}
return tcs.Task;
}
///
/// Clears all values in the data store.
///
public Task ClearAsync()
{
this._storedResponse = new StoredResponse();
return TaskEx.Delay(0);
}
///// Creates a unique stored key based on the key and the class type.
/////The object key
/////The type to store or retrieve
//public static string GenerateStoredKey(string key, Type t)
//{
// return string.Format("{0}-{1}", t.FullName, key);
//}
}
现在您将调用 savedDataStore 而不是调用 filedatastore
//Now we load our saved refreshToken. Probably from the DB someplace but this works
StoredResponse myStoredResponse = new StoredResponse(tbRefreshToken.Text);
// Now we pass a SavedDatastore with our StoredResponse.
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets { ClientId = "YourClientId", ClientSecret = "YourClientSecret" },
new[] { DriveService.Scope.Drive,
DriveService.Scope.DriveFile },
"user",
CancellationToken.None,
new SavedDataStore(myStoredResponse)).Result; }
我有一个教程和示例项目。目前使用 Google Drive 范围,您可以轻松更改这些范围,示例项目位于底部。 Google Oauth2 C#
关于c# - Google Calendar API 身份验证 .NET 浏览器窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23669497/