Xamarin应用更新时如何避免缓存被清除以保留会话令牌
Xamarin应用更新后保留会话令牌的解决方案
一、MonkeyCache更新后丢失令牌的修复
MonkeyCache默认使用系统缓存目录,该目录在应用更新时可能被清理,将存储位置改为持久化目录即可解决:
iOS端(AppDelegate.cs)
// 切换到Documents目录存储,更新时不会被清除 var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); Barrel.ApplicationId = NSBundle.MainBundle.BundleIdentifier; Barrel.Current.Configure(cacheDirectory: documentsPath);
Android端(MainActivity.cs)
// 切换到Files目录存储,更新时不会被清除 var filesPath = Application.Context.FilesDir.AbsolutePath; Barrel.ApplicationId = PackageName; Barrel.Current.Configure(cacheDirectory: filesPath);
二、MSAL GetAccountsAsync更新后返回null的修复
MSAL默认缓存依赖Keychain(iOS)/SharedPreferences(Android),更新后丢失通常是缓存配置不兼容,按以下步骤修复:
1. 初始化MSAL时指定兼容的缓存容器
手动配置缓存序列化逻辑,确保跨版本能读取缓存:
var pca = PublicClientApplicationBuilder .Create("你的ClientId") .WithTenantId("你的TenantId") #if __IOS__ .WithIosKeychainSecurityGroup("com.你的公司.keychain组名") // 和Entitlements.plist配置一致 #endif #if __ANDROID__ .WithAndroidRedirectUri($"msal你的ClientId://auth") #endif .Build(); // 绑定缓存读写逻辑 pca.UserTokenCache.SetBeforeAccess(args => { var cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "msal_cache.bin"); args.TokenCache.DeserializeMsalV3(File.Exists(cachePath) ? File.ReadAllBytes(cachePath) : null); }); pca.UserTokenCache.SetAfterAccess(args => { if (args.HasStateChanged) { var cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "msal_cache.bin"); File.WriteAllBytes(cachePath, args.TokenCache.SerializeMsalV3()); } });
2. iOS端额外配置Keychain权限
在Entitlements.plist中添加Keychain Groups,确保应用更新后能访问原有Keychain缓存:
<key>keychain-access-groups</key> <array> <string>$(AppIdentifierPrefix)com.你的公司.keychain组名</string> </array>
三、兜底方案:使用SecureStorage存储令牌
如果上述方法仍有问题,直接用Xamarin.Essentials提供的SecureStorage,这是跨平台的安全持久化存储,更新时绝对不会丢失令牌:
// 存储令牌 await SecureStorage.SetAsync("access_token", 获取到的令牌); // 读取令牌 var accessToken = await SecureStorage.GetAsync("access_token"); if (!string.IsNullOrEmpty(accessToken)) { Helpers.Settings.IsLoged = true; }
iOS端需在Entitlements.plist中开启Keychain权限,Android端无需额外配置。
内容的提问来源于stack exchange,提问作者Keru David
相关产品推荐
相关产品推荐

