使用Swift和客户端凭据调用安全API

使用Swift和客户端凭据调用安全API,swift,api,networking,Swift,Api,Networking,我的目标是调用一个API,该API受OAuth 2.0保护,具有授予类型的客户端凭据。我不一定对代码示例感兴趣,只是对Swift架构有很好了解的人提供的最佳实践。尽管举个例子会很好 总之,我试图实现以下内容: 当按下按钮时,它调用函数“getStock() getStock()函数调用另一个类中的getToken()函数来请求承载令牌 进行网络调用,并在http调用中返回令牌。网络调用完成后,令牌将传递回getStock()函数,通过在头中包含承载令牌来进行API调用 我已经创建了一个OAuth

我的目标是调用一个API,该API受OAuth 2.0保护,具有授予类型的客户端凭据。我不一定对代码示例感兴趣,只是对Swift架构有很好了解的人提供的最佳实践。尽管举个例子会很好

总之,我试图实现以下内容:

  • 当按下按钮时,它调用函数“getStock()
  • getStock()函数调用另一个类中的getToken()函数来请求承载令牌
  • 进行网络调用,并在http调用中返回令牌。网络调用完成后,令牌将传递回getStock()函数,通过在头中包含承载令牌来进行API调用
  • 我已经创建了一个OAuthGenerator类,我可以调用它,它成功地返回了一个令牌

    我的问题是我不知道如何将访问令牌返回到另一个类,而网络调用的性质意味着我需要等待返回的值,然后再调用实际的API

    如果你建议改用Swift网络库,我很想看看。我看了一些,但找不到使用客户端凭据的示例实现

        func getStock() {
    
            OAuthTokenGenerator().getToken()
    
            var request = URLRequest(url: URL(string: "https://myapi.com/stock)!,timeoutInterval: Double.infinity)
    
            request.addValue("Bearer " + accessToken, forHTTPHeaderField: "Authorization")
    
                     request.httpMethod = "GET"
    
                     URLSession.shared.dataTask(with: request) { (data, response, err) in
                     guard let data = data else { return }
                     do {
                     let stock = try
                        JSONDecoder().decode(Stock.self, from: data) // decode JSON object based on above Constructor
                             DispatchQueue.main.async { // Async make call when ready
    
                                self.StockLabel.text = stock.stockTotal
                                self.current_fy.text = stock.currentFYTotal
                                self.previous_fy.text = stock.previousFYTotal
    
                             }
                         } catch let jsonErr {
                             print("Error serializing json:", jsonErr)
                         }
                     }.resume()
    
         }
    
        @IBAction func buttonSubmit(_ sender: UIButton) {
            getStock()
        }
    
    

    你的问题有点让人困惑,我想你应该在第一次应用程序启动之前将令牌保存在core data framework中,这样你就可以随时调用它,并且担心它总是出现在应用程序中,因为核心数据值是一个持久值,即使你杀死应用程序,它也始终存在。保存后,每次登录时,您都可以在if中调用它,在if中,您声明如果接收到的令牌与核心数据中保存的令牌相同,则它将进入,否则会显示一个解释错误的警报

    import Foundation
    
    class OAuthTokenGenerator {
    
        func getToken() {
    
            let headers = ["content-type": "application/x-www-form-urlencoded"]
    
                let postData = NSMutableData(data: "grant_type=client_credentials".data(using: String.Encoding.utf8)!)
                postData.append("&client_id=*****************".data(using: String.Encoding.utf8)!)
                postData.append("&client_secret=*****************".data(using: String.Encoding.utf8)!)
    
                let apiURL = "https://example-api-token-generator.com/identity/v1/token"
    
                guard let url = URL(string: apiURL) else { return }
                var request = URLRequest(url: url)
    
                request.httpMethod = "POST"
                request.allHTTPHeaderFields = headers
                request.httpBody = postData as Data
    
                URLSession.shared.dataTask(with: request) { (data, response, err) in
                guard let data = data else { return }
                do {
                let token = try
                JSONDecoder().decode(Token.self, from: data) // decode JSON object based on above Constructor
                        DispatchQueue.main.async { // Async make call when ready
    
                            print(token.access_token)
    
                        }
    
                    } catch let jsonErr {
                        print("Error serializing json:", jsonErr)
                    }
    
                }.resume()
        }
    
    
    }