React Native集成ForgeRock及处理RefreshToken时重启获取AccessToken失败
问题:应用重启/杀死后无法获取ForgeRock AccessToken
按照ForgeRock官方React Native集成文档完成集成后,应用运行正常,但应用被杀死或重载后,调用原生方法获取AccessToken时触发错误:"Invalid SDK state: No current user for which to request access tokens"。根据文档提示,原生SDK未初始化可能导致该错误,相关代码及错误信息如下:
调用的getAccessToken方法
@objc func getAccessToken( _ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { guard let user = FRUser.currentUser else { /** * If no currently authenticated user is found, log error. */ let errorMsg = "Invalid SDK state: No current user for which to request access tokens" FRLog.e(errorMsg) reject("error", errorMsg, nil) return } user.getAccessToken { user, error in if let error = error { FRLog.e(String(describing: error)) reject("error", error.localizedDescription, error) } else if let user = user, let accessToken = user.token { let encoder = JSONEncoder() do { let data = try encoder.encode(accessToken) let string = String(data: data, encoding: .utf8) FRLog.i(string ?? "Encoding of token failed") resolve(string) } catch { reject("Error", "Serialization of tokens failed", error) } } else { let errorMsg = "Invalid SDK state: getAccessToken returned no result" FRLog.e(errorMsg) reject("error", errorMsg, nil) } } }
FRUser的getAccessToken实现
// MARK: - AccessToken /// Retrieves access_token from Keychain storage, and if current access_token is expired, then consumes refresh_token to refresh access_token, and returns FRUser with newly granted access_token /// /// - Parameter completion: Completion block which returns newly refreshed FRUser object @objc public func getAccessToken(completion:@escaping UserCallback) { if let frAuth = FRAuth.shared, let tokenManager = frAuth.tokenManager { tokenManager.getAccessToken { (token, error) in if let token = token { self.token = token self.save() completion(self, nil) } else { completion(nil, error) } } } else { FRLog.w("Invalid SDK state; missing TokenManager") completion(nil, ConfigError.invalidSDKState) } }
FRUser的currentUser代码
/** Singleton instance represents currently authenticated user. ## Note ## If SDK has not been started using *FRAuth.start()*, *FRUser.currentUser* returns nil even if user session has previously authenticated, and valid. *FRUser.currentUser* would only returns an object when there is either or both of following: - Session Token authenticated by AM's Authentication Tree - OAuth2 token set issued by previously authenticated Session Token */ @objc public static var currentUser: FRUser? { get { if let staticUser = _staticUser { return staticUser } else if let frAuth = FRAuth.shared { FRLog.v("FRUser retrieved from SessionManager") if let accessToken = try? frAuth.keychainManager.getAccessToken() { _staticUser = FRUser(token: accessToken) } else if let _ = frAuth.keychainManager.getSSOToken() { _staticUser = FRUser(token: nil) } return _staticUser } FRLog.w("Invalid SDK State: FRUser is returning 'nil'.") return nil } }
触发的错误信息
Invalid SDK state: No current user for which to request access tokens
排查与解决步骤
1. 确保应用启动时优先初始化ForgeRock SDK
从FRUser.currentUser的注释明确可知:必须先调用FRAuth.start()初始化SDK,否则即使钥匙串中有有效会话,currentUser也会返回nil。需在应用启动的最早期执行初始化,比如在AppDelegate的didFinishLaunchingWithOptions中:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 优先初始化ForgeRock SDK do { try FRAuth.start() } catch { FRLog.e("Failed to start ForgeRock SDK: \(error)") } // 其他React Native初始化逻辑 return true }
2. 检查钥匙串配置与访问权限
ForgeRock SDK依赖钥匙串存储会话和令牌,需确认:
Entitlements.plist中已开启钥匙串访问权限- SDK初始化配置包含正确的钥匙串组(若使用App Groups)
- 用户认证后,
accessToken或SSOToken确实被写入钥匙串(可在认证后直接调用frAuth.keychainManager.getAccessToken()验证)
3. 避免过早调用令牌获取方法
确保SDK初始化完成后,再调用getAccessToken。若由React Native侧触发调用,可在原生模块中添加初始化完成回调,或延迟执行令牌获取逻辑。
4. 验证令牌持久化逻辑
检查FRUser的save()方法是否正确将令牌写入钥匙串:
- 确认
save()调用了keychainManager.setAccessToken()或相关持久化API - 验证令牌过期后,刷新逻辑能正确更新钥匙串中的令牌
5. 调试钥匙串读取流程
在FRUser.currentUser的getter中添加日志,确认:
FRAuth.shared不为nil(SDK已初始化)keychainManager.getAccessToken()/getSSOToken()能读取到值
若读取失败,说明令牌未被正确持久化或钥匙串访问异常
内容的提问来源于stack exchange,提问作者Jalson1982
相关产品推荐
相关产品推荐

