我正在尝试将 Xamarin.Auth 与Xamarin Google-API https://github.com/xamarin/google-apis登录 Google 并访问云端硬盘。我已经设法让几乎一切正常工作,但身份验证令牌似乎在大约一个小时后过期。一切都运行良好一段时间,但大约一个小时后,当我尝试访问时,我收到无效凭据 [401] 错误和泄漏:
Google.Apis.Requests.RequestError
Invalid Credentials [401]
Errors [
Message[Invalid Credentials] Location[Authorization - header] Reason[authError] Domain[global]
]
: GoogleDriveAgent: FetchRemoteFileList() Failed! with Exception: {0}
[0:] Google.Apis.Requests.RequestError
Invalid Credentials [401]
Errors [
Message[Invalid Credentials] Location[Authorization - header] Reason[authError] Domain[global]
]
: GoogleDriveAgent: FetchRemoteFileList() Failed! with Exception: {0}
objc[37488]: Object 0x7f1530c0 of class __NSDate autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[37488]: Object 0x7f151e50 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
//...more leaks.
我想确保我按预期使用 Xamarin.Auth 和 Google API,所以这是我的代码:
在我的 GoogleDriveService 类中,我有一个帐户存储和一个已保存的帐户:
AccountStore Store {
get {
if (m_store == null)
m_store = AccountStore.Create ();
return m_store;
}
}
Account SavedAccount {
get {
var savedAccounts = Store.FindAccountsForService ("google");
m_savedAccount = (savedAccounts as List<Account>).Count > 0 ? (savedAccounts as List<Account>) [0] : null;
return m_savedAccount;
}
}
我初始化一个会话并启动服务:
void InitializeSession ()
{
Authenticator = new GoogleAuthenticator (ClientID, new Uri (RedirectUrl), GoogleDriveScope);
Authenticator.Completed += HandleAuthenticationCompletedEvents;
if (SavedAccount != null) {
Authenticator.Account = SavedAccount;
StartService ();
}
UpdateSignInStatus ();
}
bool StartService ()
{
try {
Service = new DriveService (Authenticator);
return true;
} catch (Exception ex) {
// Log exception
return false;
}
}
...并响应身份验证完成事件:
void HandleAuthenticationCompletedEvents (object sender, AuthenticatorCompletedEventArgs e)
{
if (e.IsAuthenticated) { // Success
UpdateSignInStatus();
Store.Save (e.Account, "google");
Authenticator.Account = e.Account;
StartService();
LoginController.DismissViewController(true, null);
} else { // Cancelled or no success
UpdateSignInStatus();
LoginController.DismissViewController(true, null);
LoginController = null;
InitializeSession (); // Start a new session
}
}
同样,在一段时间内一切正常,但随后身份验证就会过期。我明白那个它应该 https://developers.google.com/accounts/docs/OAuth2#expiration,但我认为保存在 AccountStore 中的凭据应该仍然有效。
In the Xamarin.Auth 入门文档 http://components.xamarin.com/gettingstarted/xamarin.auth,它表示再次调用“保存”将覆盖凭据,并且“这对于使帐户对象中存储的凭据过期的服务很方便”。听起来很有希望...
所以我尝试了另一种方法:有一个 IsSignedIn 属性,它总是覆盖 getter 中的凭据......
public bool IsSignedIn {
get {
if (Authenticator == null) {
m_isSignedIn = false;
return m_isSignedIn;
}
if (Authenticator.Account != null) {
Store.Save (Authenticator.Account, "google"); // refresh the account store
Authenticator.Account = SavedAccount;
m_isSignedIn = StartService ();
} else {
m_isSignedIn = false;
}
return m_isSignedIn;
}
}
...然后我在任何 API 调用(获取元数据、下载等)之前访问 IsSignedIn。它不起作用:我仍然收到上面显示的过期凭据错误。
这种情况是否需要刷新令牌 https://github.com/xamarin/Xamarin.Auth/issues/47?我究竟做错了什么?