使用 Swift(使用 SwiftJWT)和 REST API 连接到 Apple Store Connect - 失败并出现 401

Posted

技术标签:

【中文标题】使用 Swift(使用 SwiftJWT)和 REST API 连接到 Apple Store Connect - 失败并出现 401【英文标题】:Connecting to Apple Store Connect using Swift (with SwiftJWT) and REST API's - failing with 401 【发布时间】:2021-07-09 15:51:05 【问题描述】:

我正在尝试通过他们的 REST API 连接到 Apple Store Connect。虽然这在几天前工作,但我无法弄清楚它为什么停止工作。现在我无法通过身份验证,即我向服务器响应的每个请求都是 401。我错过了什么吗?

我做什么:

    生成 JWT(我使用 SwiftJWT 库) 创建带有相关标头集的 URLRequest 对象 使用创建的 URLRequest 调用 API

生成 JWT:

func generateJWT() -> String 
        var signedJWT = ""
        
        let pathToKey = URL(fileURLWithPath: "AuthKey.p8")
        
        // Header - alg is automatically set to ES256, and so is typ is set to JWT
        let header = Header(kid: "********")
        
        // Represents the payload being used to generate the JWT
        let claim = MyClaims(iss: "***", exp: Date(timeIntervalSinceNow: 3600), aud: "appstoreconnect-v1")
        var jwt = JWT(header: header, claims: claim)
        
        do 
            let privateKey: Data = try Data(contentsOf: pathToKey, options: .alwaysMapped)
            let jwtSigner = JWTSigner.es256(privateKey: privateKey)
            
            signedJWT = try jwt.sign(using: jwtSigner)
         catch 
            print("There was an error getting the key...\(error)")
        
        
        return signedJWT
    

然后我创建一个包含所有必需标头的 URLRequest:

func createRequest(with jwt: String) -> URLRequest? 
        guard let url = URL(string: "https://api.appstoreconnect.apple.com/v1/users") else 
            print("Ugh! Something went wrong with the URL provided...")
            return nil
        
        
        var request = URLRequest(url: url)
        request.setValue(jwt, forHTTPHeaderField: "Authorization")
        request.httpMethod = "GET"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        return request
    

然后我提出请求:

func performRequest(request: URLRequest) -> Bool 
        var status = false
        
        URLSession.shared.dataTask(with: request)  data, response, error in
            if let data = data 
                if let decodedResponse = try? JSONDecoder().decode([String:String].self, from: data) 
                    // For this sample project we do nothing other than celebrate
                    
                    // everything is good, so we can exit
                    status = true
                    return
                
            
            
            // if we're still here it means there was a problem
            print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
            print("Fetch failed: \(String(describing: response))")
            status = false

        .resume()
        
        return status
    

响应

Fetch failed: Optional(<NSHTTPURLResponse: 0x600002ac95e0>  URL: https://api.appstoreconnect.apple.com/v1/users   Status Code: 401, Headers 
    "Content-Length" =     (
        350
    );
    "Content-Type" =     (
        "application/json"
    );
    Date =     (
        "Fri, 09 Jul 2021 15:47:27 GMT"
    );
    Server =     (
        "daiquiri/3.0.0"
    );
    "Strict-Transport-Security" =     (
        "max-age=31536000; includeSubDomains"
    );
    "x-apple-jingle-correlation-key" =     (
        XXXXXXXXXXX
    );
    "x-daiquiri-instance" =     (
        "daiquiri:38493001:pv50p00it-hyhk12043901:7987:21HOTFIX14"
    );
 )

我做错了什么或遗漏了什么?

【问题讨论】:

try? JSONDecoder().decode 丢弃有用的信息。 App Store Connect API 也有这个问题。几个月来它一直运行良好,但我注意到 JWT 元素不再工作。使用另一种方法生成 JWT 工作正常,但使用 SwiftJWT,它不再工作。 我已经发布了解决方案。这似乎与有效期有关。联系 Apple 并没有帮助,所以我不确定他们是否进行了任何更改,因为设置为 3600 的到期时间已经成功运行了数周。 【参考方案1】:

我通过 TSI 请求和 Apple Store Connect 帮助票联系了 Apple。在这两种情况下,它们都没有太大帮助。

在尝试了不同的方法后,我设法找到了问题并重现了它。

将有效期从 3600 秒更改为 1200 秒似乎可以解决问题。

From: exp: Date(timeIntervalSinceNow: 3600)
To: exp: Date(timeIntervalSinceNow: 1200)

Response:
< HTTP/2 200 
< server: daiquiri/3.0.0
< date: Thu, 15 Jul 2021 07:15:44 GMT
< content-type: application/json
< content-length: 964

【讨论】:

以上是关于使用 Swift(使用 SwiftJWT)和 REST API 连接到 Apple Store Connect - 失败并出现 401的主要内容,如果未能解决你的问题,请参考以下文章

无法使用ffmpeg在ios swift中获得机器人声音吗?

Swift 4:如何使用 Alamofire 在参数中发布文件?

对 Swift 3.0 的领域支持

Swift - 失败:Alamofire 中的 responseValidationFailed(状态码 401)

41 正则中匹配多个字符串匹配任意单个字符正则中使用字符串重复可选和特殊字符

重新验证用户凭据 Swift