我目前正在对家庭自动化API进行逆向工程。我想用我自己的应用程序管理所有设置 - 因为公司目前实际上没有家庭自动化应用程序。
无论如何 - 我已经用我的智能家居设备管理了身份验证。为了不让它太复杂:我需要http 摘要身份验证来进行最终通信。 我已经能够使用 curl 通过命令行连接到我的设备 - 不幸的是,这在 Swift 中无法按计划工作。
curl -X POST -d '{"key": "value"}' https://192.168.0.0:1/action -k -s --digest --user username:password
翻译成斯威夫特:
(1(使用阿拉莫火
import Alamofire
let data: [String: any] = ["key": "value"]
let request = Alamofire.request("https://192.168.0.0:1/action", method: HTTPMethod.post, parameters: data);
request.authenticate(user: "username", password: "password")
request.responseJSON { response in
// leads to error because of invalid self signed certificate of the smart home device ("https:")
}
Alamofire注意:我想在这种情况下使用AF等外部库没有多大意义 - 有一些未解决的问题不会让上述代码工作。(自签名证书会产生问题,使用自定义管理器实例覆盖内部内容也会导致问题( - 我已经花了几个小时相信我。
(2(不使用阿拉莫火:)
extension ViewController: URLSessionDelegate {
public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
completionHandler(.useCredential, urlCredential)
}
}
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
do {
let jsonData = try JSONSerialization.data(withJSONObject: data, options: .prettyPrinted)
request.httpBody = jsonData;
let task = session.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
// success
}
}
task.resume()
} catch { }
上面的代码似乎工作正常 - 问题是我还没有实现摘要身份验证 - 因为我找不到任何方法可以做到这一点。
如果有人获得一些提示,如何根据用户名和密码生成身份验证标头,那将非常有帮助
编辑
Curl 使用此授权标头:
> Digest username="username",
realm="XTV",
nonce="MTU5MDcNc2UxNjQ3OTo1YzMwYjc3YjIxMzAAAGQ5Nzg2NzUzMmRkZGU1ZVVlYw==",
uri="/action",
cnonce="MTExOTZlZmI1MjBlYWU0MTIzMDBmNDE0YTkWzJl1MDk=",
nc=00000001,
qop=auth,
response="2ba89269645e2aa24ac6f117d85e190c",
algorithm="MD5"
是否有可能在 Swift 中生成此标头?
当服务器正确返回具有正确摘要设置的WWW-Authenticate
标头时,URLSession
和 Alamofire 通过URLCredential
(这是authenticate()
在 Alamofire 中使用的(自动支持摘要式身份验证。
您可以手动生成标头,但由于摘要过程的复杂性,我不建议这样做。我发现维基百科页面足够彻底,可以手动实施该标准。