ios - 在 didFinishLaunchingWithOptions 检查无效的用户令牌火力库
问题描述
根据 Google 支持,检测撤销的 firebase 令牌的唯一方法是向我的 Firestore发出读取请求并捕获FIRAuthErrorCodeUserTokenExpired错误。
我在我的 iOS 应用程序的didFinishLaunchingWithOptions()中尝试了它。数据读取正确,但应该有一个错误,因为我停用了测试用户帐户(令牌应该被撤销)。不幸的是,Firebase 仍然处理请求并登录用户而不会引发错误。
对于应该尽可能安全的应用程序,如果您仍然登录到应用程序,尽管您的令牌已经被撤销,这是非常不理想的。
这是我的代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
window = UIWindow()
if Auth.auth().currentUser == nil { // check if there is a User logged in
window?.rootViewController = LoginViewController() // set the MainTabBarController as the root (start) controller
} else{
if let uid = Auth.auth().currentUser?.uid{
let firRef = Firestore.firestore().collection("idols").document(uid)
firRef.getDocument { (document, error) in
if let err = error {
print(err)
self.window?.rootViewController = LoginViewController()
}else{
guard let doc = document, let data = doc.data() else {return}
guard let username = data["username"] as? String, let uid = data["uid"] as? String, let biography = data["biography"] as? String else {return}
self.activeUser = User(uid: String(uid), username: username, biography: biography)
print(self.activeUser)
self.window?.rootViewController = MainTabBarController()
}
}
}
window?.rootViewController = LoginViewController()
}
return true
}
这是我的 Firebase 规则:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
我知道规则尚未完全调整,但在我看来,Firebase 应该会抛出错误,因为令牌已过期。我知道我还没有检查正确的错误,但是if let无论如何都不会被调用。
我检查了多个资源,包括与该主题相对应的Firebase 文档,但该文档仅涵盖如何在 Web 中检测被撤销的令牌,而不是在 iOS 或 Android 上。
除此之外,我检查了一个堆栈溢出条目,但它没有有用的正确答案,所以我决定在这里发布我自己的:
有谁知道如何在 iOS 上立即检测已撤销令牌的正确方法?
如果这个问题没有完美地表述,我很抱歉。我还是堆栈溢出的新手,所以请善待:)
解决方案
我找到了以下解决方案:
在didFinishLaunchingWithOptions添加以下代码:
if Auth.auth?.currentUser == nil {
// You need to prompt the user login interface
} else {
Auth.auth().currentUser?.reload(completion: { (error) in
if error != nil {
if let err = error as NSError?{
if let error = AuthErrorCode(rawValue: err.code){
switch error{
// You need to prompt the user login interface
case .invalidCredential: print("Invalid credentials")
case .invalidUserToken: print("Invalid User Token")
case .userTokenExpired: print("User Token Expired")
case .invalidCustomToken: print("Invalid Custom Token")
case .customTokenMismatch: print("Custom token mismatch")
case .userDisabled: print("User disabled")
case .userNotFound: print("User not found")
default: print("call default error")
}
}
}
}
else {
print("Valid Token")
}
})
}
啊,不要忘记在运行此代码之前初始化 Firebase(否则您将无权访问 Firebase Auth)
推荐阅读
- python - 如何在 settings.py 文件中隐藏 EMAIL_HOST_PASSWORD?
- android - 使用 Dagger 将 Activity 绑定到 LifecycleOwner
- ionic-framework - Ionic 中的嵌套 JSON 数据
- razor - 如何在 .Net Core 项目的布局中包含 font-awesome(通过 nuget 安装)?
- python - 如何生成一个python字典comphrension,将键生成为值的范围函数?
- python - 如何访问烧瓶中任务队列提交的作业数据?
- apache-spark - PySpark StandardScaler 在双列上抛出错误
- reactjs - 创建项目时缺少模块 minizlib
- entity-framework-core - EF Core:对 IQueryable 进行分段以仅重用和加载选定属性的策略
- javascript - 用于预执行某些代码的 Webpack 插件