Swift iOS前端对接Django REST Framework后端如何判断用户登录状态
登录状态判断优化方案
首选方案:前后端配合实现轻量校验
这个方案可以完全对齐你之前用Firebase的调用习惯,代码整洁度高,性能也更好。
后端(Django REST Framework)改动
新增一个无返回体的token校验接口,不需要拉取用户全量信息,仅通过状态码判断token有效性:
# 若你使用djangorestframework-simplejwt做JWT认证,直接用内置的TokenVerifyView也可以,不用自己写 from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response @api_view(['GET']) @permission_classes([IsAuthenticated]) def token_verify(request): # 权限类会自动校验Authorization头里的token,通过才会进到这里 return Response(status=200)
token失效时接口会自动返回401状态码,不需要额外做错误处理。
前端(Swift)改动
封装全局单例AuthManager统一管理所有鉴权相关逻辑,所有和登录、token、用户信息相关的操作都收口在这里,上层业务不用感知底层实现:
struct AuthenticatedUser: Codable, Hashable { let username: String let email: String } class AuthManager { static let shared = AuthManager() private init() {} private let tokenKey = "com.yourapp.userAccessToken" // 登录成功后缓存用户信息,不需要每次启动都重复请求 var currentUser: AuthenticatedUser? // 快速判断登录状态,和Firebase的API风格对齐 var isLoggedIn: Bool { UserDefaults.standard.string(forKey: tokenKey) != nil && currentUser != nil } // 冷启动时调用一次做异步校验,更新登录状态 func validateLoginStatus(completion: @escaping (Bool) -> Void) { guard let token = UserDefaults.standard.string(forKey: tokenKey) else { completion(false) return } // 调用后端校验接口 var req = URLRequest(url: URL(string: "https://yourdomain.com/api/auth/verify")!) req.httpMethod = "GET" req.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") URLSession.shared.dataTask(with: req) { [weak self] data, resp, err in DispatchQueue.main.async { guard let httpResp = resp as? HTTPURLResponse, httpResp.statusCode == 200, err == nil else { // 校验失败,清空本地缓存 self?.clearAuthData() completion(false) return } // 校验成功如果还没缓存用户信息,就拉一次存起来,后续不用再请求 if self?.currentUser == nil { self?.fetchUserInfo(token: token) { user in self?.currentUser = user completion(user != nil) } } else { completion(true) } } }.resume() } // 登录、登出方法统一收口 func login(token: String, user: AuthenticatedUser) { UserDefaults.standard.set(token, forKey: tokenKey) currentUser = user } func logout() { clearAuthData() } private func clearAuthData() { UserDefaults.standard.removeObject(forKey: tokenKey) currentUser = nil } private func fetchUserInfo(token: String, completion: @escaping (AuthenticatedUser?) -> Void) { // 这里写你原来拉取用户信息、解码的逻辑 } }
封装完成后,你业务层的跳转逻辑可以写得和Firebase几乎一致:
if AuthManager.shared.isLoggedIn { let vc = HomeViewController() present(vc, animated: true) }
无需改后端的优化方案
如果你暂时不想调整后端接口,直接把你现在拉取用户信息、解码判断的逻辑,放到上面AuthManager的validateLoginStatus方法里就行,上层调用逻辑完全不变,同样可以解决代码冗长杂乱的问题。
可选进阶优化
如果你用的是JWT token,可以增加本地预校验逻辑:先解析token里的过期时间,未过期的情况下可以不用发请求到后端,直接返回登录成功,只有token即将过期或解析失败时再调用后端接口校验,能进一步提升响应速度。
内容的提问来源于stack exchange,提问作者Arkash Vijayakumar
相关产品推荐
相关产品推荐

