You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:54:01