原生Android集成Azure AD B2C MSAL如何避免每次启动调用静默续期接口
优化方案
核心思路
本地缓存有效access token及其过期时间,应用启动时优先校验本地缓存的有效性,仅在缓存不存在/已过期时才调用acquireTokenSilentAsync接口,避免每次启动都触发MSAL的静默请求。
具体实现步骤
1. 新增Token缓存逻辑
每次通过交互式登录或静默获取拿到有效Token后,将Token本身和过期时间持久化存储到SharedPreferences中:
// 在getAuthInteractiveCallback和getAuthSilentCallback的onSuccess回调中新增以下逻辑 @Override public void onSuccess(IAuthenticationResult authenticationResult) { // 原有业务逻辑保留 String accessToken = authenticationResult.getAccessToken(); long expiresAt = authenticationResult.getExpiresOn().getTime(); // 持久化存储 SharedPreferences authSp = getSharedPreferences("azure_auth_cache", MODE_PRIVATE); authSp.edit() .putString("cached_access_token", accessToken) .putLong("token_expires_at", expiresAt) .apply(); }
2. 修改启动时的Token校验逻辑
修改loadAccount方法中账号加载完成后的逻辑,不要直接调用静默获取接口,先校验本地缓存有效性:
@Override public void onAccountLoaded(@Nullable IAccount activeAccount) { mAccount = activeAccount; if (activeAccount != null) { Log.d("SKT","Account Already Signed In"); SharedPreferences authSp = getSharedPreferences("azure_auth_cache", MODE_PRIVATE); String cachedToken = authSp.getString("cached_access_token", null); long expiresAt = authSp.getLong("token_expires_at", 0); long currentTime = System.currentTimeMillis(); // *建议预留3-5分钟的缓冲时间,避免token临界过期导致业务请求失败* boolean isTokenValid = cachedToken != null && currentTime < (expiresAt - 5 * 60 * 1000); if (isTokenValid) { // 缓存有效,直接使用本地Token,跳过静默请求 mAccessToken = cachedToken; // 直接走后续业务初始化逻辑 initBusinessFlow(); } else { // 缓存失效,才调用静默获取接口 mSingleAccountApp.acquireTokenSilentAsync( getScopes(), B2CConfiguration.getAuthorityFromPolicyName("B2C_1_SignInSignUp"), getAuthSilentCallback() ); } } }
3. 补充边界处理逻辑
- 用户退出登录时,同步清空SharedPreferences中缓存的Token和过期时间,避免账号切换时拿到旧账号的无效Token
- 业务接口请求时如果返回401未授权状态码,无论本地缓存是否到期,都主动触发一次
acquireTokenSilentAsync更新Token后重试请求,处理Token被服务端提前吊销的极端情况
内容的提问来源于stack exchange,提问作者sooraj
相关产品推荐
相关产品推荐

