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

Swift封装AWS Amplify全局fetchSession获取idToken报错问题

全局获取AWS Cognito有效idToken实现方案

报错原因

  • 第一次报Unexpected non-void return value in void function:Amplify.Auth.fetchAuthSession是异步方法,其入参的completion闭包返回值类型为Void,在闭包内部写return返回值无法被外部函数接收,不符合闭包定义所以报错。
  • 第二次报类型不匹配:手动给completion闭包声明了-> AnyObject返回值,和Amplify SDK定义的闭包类型(Result<AuthSession, AuthError>) -> Void冲突,编译器无法识别该参数类型。

实现逻辑说明

AWS Cognito的idToken默认有效期为5分钟,Amplify SDK内部已经内置了自动刷新逻辑,只要用户登录态有效,调用接口时会自动判断token是否临近过期,自动通过refreshToken换取新的有效token,不需要开发者自行编写定时刷新逻辑。只需要封装全局可访问的异步方法,每次需要token时直接调用获取最新有效值即可,不要自行本地缓存token避免拿到过期值。

完整实现代码

推荐使用Swift 5.5+的async/await语法封装,代码更简洁易读,全局通过单例调用:

import Amplify
import AWSCognitoAuthPlugin

class AuthManager {
    // 全局单例,应用内任意位置可直接访问
    static let shared = AuthManager()
    private init() {}
    
    /// 获取最新有效Cognito idToken
    /// - Throws: 登录态失效、网络错误等异常
    /// - Returns: 有效的idToken字符串
    func fetchIdToken() async throws -> String {
        let session = try await Amplify.Auth.fetchAuthSession()
        guard let cognitoTokenProvider = session as? AuthCognitoTokensProvider else {
            throw NSError(
                domain: "AuthServiceError",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "当前登录状态异常,无法获取用户令牌"]
            )
        }
        let tokens = try cognitoTokenProvider.getCognitoTokens().get()
        return tokens.idToken
    }
}

如果需要兼容iOS 15以下的系统版本,可以使用completion回调的封装方式:

func fetchIdToken(completion: @escaping (Result<String, Error>) -> Void) {
    Amplify.Auth.fetchAuthSession { result in
        switch result {
        case .success(let session):
            guard let cognitoTokenProvider = session as? AuthCognitoTokensProvider else {
                completion(.failure(NSError(
                    domain: "AuthServiceError",
                    code: -1,
                    userInfo: [NSLocalizedDescriptionKey: "当前登录状态异常,无法获取用户令牌"]
                )))
                return
            }
            do {
                let tokens = try cognitoTokenProvider.getCognitoTokens().get()
                completion(.success(tokens.idToken))
            } catch {
                completion(.failure(error))
            }
        case .failure(let error):
            completion(.failure(error))
        }
    }
}

调用示例

async/await 调用(推荐)

在任意需要获取token的位置(比如网络请求拦截器、接口调用前)通过Task包裹调用:

// 示例:给网络请求添加Authorization头
Task {
    do {
        let validToken = try await AuthManager.shared.fetchIdToken()
        var request = URLRequest(url: URL(string: "你的接口地址")!)
        request.setValue("Bearer \(validToken)", forHTTPHeaderField: "Authorization")
        // 执行后续网络请求逻辑
    } catch {
        print("获取token失败:\(error.localizedDescription)")
        // 可在此处处理登录态失效逻辑,比如跳转至登录页
    }
}

回调方式调用

AuthManager.shared.fetchIdToken { [weak self] result in
    switch result {
    case .success(let idToken):
        // 拿到有效token执行业务逻辑
        print("获取token成功:\(idToken)")
    case .failure(let error):
        // 处理错误
        print("获取token失败:\(error.localizedDescription)")
    }
}

内容的提问来源于stack exchange,提问作者SadDeveloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:15:19