В настоящее время я нахожусь в процессе реинжиниринга API домашней автоматизации. Я хочу управлять всеми настройками с помощью моего собственного приложения, потому что на самом деле нет текущего приложения для домашней автоматизации от компании.
В любом случае - я уже выполнил аутентификацию с помощью своего устройства SmartHome . Чтобы не усложнять: мне нужно http-дайджест-аутентификация для окончательного общения. Я уже смог подключиться к своему устройству через командную строку с помощью curl - к сожалению, это не работает в Swift, как планировалось.
curl -X POST -d '{"key": "value"}' https://192.168.0.0:1/action -k -s --digest --user username:password
Переведено на Swift:
(1) Использование Alamofire
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) Использование not Alamofire:)
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 { }
Похоже, что приведенный выше код работает нормально - проблема в том, что я еще не реализовал дайджест-аутентификацию - потому что я не нашел способа, как это сделать.
Было бы очень полезно, если бы кто-нибудь получите несколько советов, как сгенерировать заголовок Auth на основе имени пользователя и пароля
Edit
Curl использует этот Authorization header:
> Digest username="username",
realm="XTV",
nonce="MTU5MDcNc2UxNjQ3OTo1YzMwYjc3YjIxMzAAAGQ5Nzg2NzUzMmRkZGU1ZVVlYw==",
uri="/action",
cnonce="MTExOTZlZmI1MjBlYWU0MTIzMDBmNDE0YTkWzJl1MDk=",
nc=00000001,
qop=auth,
response="2ba89269645e2aa24ac6f117d85e190c",
algorithm="MD5"
Есть ли возможность сгенерировать этот заголовок в Swift?