iOS Facebook登录Access Token刷新问题:90天未交互致令牌无效
Hey there, I’ve dealt with this exact scenario plenty of times building iOS apps with Facebook Login, so let’s walk through a clean, user-friendly solution.
First, to align on the core issue (which you already have a good grasp of): Facebook’s policy dictates that access tokens expire for users who haven’t actively engaged with your app—via login or permission-granted actions—in 90+ days. Silent token refreshes won’t work here; you have to prompt the user to re-authenticate properly.
Here’s a step-by-step approach tailored for iOS:
1. Proactively Check Token Validity Before API Calls
Instead of waiting for the error to pop up, add a quick pre-check before making any Facebook Graph API requests. Using the Facebook iOS SDK, you can verify the current token’s status with ease:
import FBSDKLoginKit func isFacebookTokenValid() -> Bool { guard let token = AccessToken.current else { return false // No existing token found } // Check if token is expired or revoked by the user/Facebook if token.isExpired || token.hasBeenRevoked { return false } // For extra certainty, you could add a server-side call to Facebook's debug_token endpoint // (Avoid doing this client-side to protect your app secret) return true }
2. Catch the Expired Token Error & Trigger Re-Auth
When you hit the specific error (The access token is invalid since the user hasn't engaged the app in longer than 90 days), it’ll come with error code 190—a standard Facebook API code for invalid tokens. Catch this in your request handler:
func fetchFacebookUserData() { guard isFacebookTokenValid() else { promptFacebookReLogin() return } let request = GraphRequest(graphPath: "me", parameters: ["fields": "name,email"]) request.start { connection, result, error in if let fbError = error as? NSError { // Target the expired token error explicitly if fbError.code == 190 { self.promptFacebookReLogin() return } // Handle other Facebook API errors print("Facebook request failed: \(fbError.localizedDescription)") return } // Process valid user data if let userData = result as? [String: Any] { print("Fetched user data: \(userData)") // Update your app's user session here } } }
3. Build a User-Friendly Re-Login Flow
Don’t just force a login screen on users—explain why re-authentication is needed to keep the experience smooth:
func promptFacebookReLogin() { let alert = UIAlertController( title: "Session Expired", message: "It’s been a while since you used this feature. Please log in again with Facebook to continue.", preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) alert.addAction(UIAlertAction(title: "Log In with Facebook", style: .default) { _ in self.initiateFacebookReAuth() }) // Present the alert from your active view controller UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true) } func initiateFacebookReAuth() { let loginManager = LoginManager() // Request the same permissions you originally asked for loginManager.logIn(permissions: ["public_profile", "email"], from: nil) { result, error in if let error = error { print("Re-login failed: \(error.localizedDescription)") return } guard let result = result, !result.isCancelled else { print("User cancelled re-login") return } // New valid token is now available via AccessToken.current print("Successfully re-authenticated!") // Resume your app's flow (e.g., re-fetch user data) self.fetchFacebookUserData() } }
4. Optimize for Future Sessions
- Track Engagement: Avoid using the Facebook token for non-essential actions. Only rely on it when users interact with Facebook-dependent features, so they don’t hit expiration unexpectedly.
- Launch-Time Check: On app launch, run a quick token validity check. If it’s invalid, either prompt re-login immediately (if Facebook features are core to your app) or wait until the user tries to use a Facebook-specific feature.
Important Note: There’s no way to bypass the 90-day re-authentication rule—it’s a Facebook policy focused on user privacy. The goal is to handle the error gracefully so users don’t get frustrated.
内容的提问来源于stack exchange,提问作者MattBlack




