You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:17:10