使用 Swift 和客户端凭证调用受保护的 API



我的目标是调用受OAuth 2.0保护的API,授权类型为客户端凭据。我不一定对代码示例感兴趣,只是对 Swift 架构有良好了解的人的最佳实践感兴趣。虽然一个例子会很棒!

我试图在总结中实现以下内容:

  1. 当按下按钮时,它会调用函数"getStock((">
  2. getStock(( 函数
  3. 调用另一个类中的 getToken(( 函数来请求持有者令牌
  4. 进行网络调用,并在 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()
}
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()
}

}

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

最新更新