Как да извикаме вътрешен API от приложение за iPhone през VPN
Класифицирайте неуспешната заявка по нейния код NSURLError, преди да пипате тунела, след което поправете точно слоя, който се е счупил.
API отговаря в Safari на същия телефон, а заявката на приложението изтича. Тази разлика обикновено не е тунелът: приложение, което вика вътрешна услуга, прави обикновена HTTPS заявка, а съществуващият VPN на устройството решава само дали тази заявка има път. Да вградите втори тунел в приложението е продуктово решение, а не поправка за изтичане. Следващото класифицира отказа по това къде се случва, използвайки повърхността за грешки, която приложението вече има.
Започнете от грешката, не от тунела
URLSession съобщава транспортни откази като NSError стойности в NSURLErrorDomain, и кодът е най-евтиното налично доказателство. Преди да промените каквато и да е конфигурация, запишете този код заедно с името на хоста, който се проваля, и изминалото време на задачата. Изтичане, отказ на име и отказ на доверие изглеждат еднакво на екрана и изискват три различни поправки. Първо класифицирайте, после прочетете раздела за този клас.
Метриките на задачата отговарят на следващия въпрос дали изобщо е установена връзка, което отделя заявка, която никога не е имала маршрут, от такава, на която сървърът е отговарял твърде дълго. Нищо от това не изисква промяна на тунела; изисква диагностиката на самата заявка да бъде отпечатана някъде, където можете да я прочетете.
Разрешаването на имена се проваля преди всичко останало
Кратко офисно име като api.corp.example обикновено зависи от домейн за търсене, който телефонът не носи, затова приложението разрешава име, което съществува само в сградата. NSURLErrorCannotFindHost е подписът. Пълното име на хоста трябва да се разреши през какъвто и резолвер да инсталира VPN, и приложението трябва да иска напълно квалифицираната форма, когато домейнът за търсене не е гарантиран. Замяната на името с адрес и изключването на проверките на сертификата премества отказа, вместо да го поправи.
Частен DNS запис и сертификат, издаден точно за това име, са поддържаната двойка. Всичко останало е заобиколно решение, което стига до потребителите.
Изтичането е въпрос на път, не на име
NSURLErrorTimedOut означава, че името е разрешено и нищо не е отговорило, което сочи към маршрута, политиката за пакети или услугата. Когато тунелът се задава за всяко приложение, друго приложение, което достига същия сървър, не казва нищо за вашата сборка, защото това съпоставяне не е споделено. Проверете дали пакетът, който изпълнявате, е в това задание, после проверете дали пътят до услугата е разрешен за него. Разработваща сборка, инсталирана извън заданието, може да стои изцяло извън тунела и да изглежда като счупен API.
Сравнение през браузър показва, че някое приложение на устройството има път. То никога не доказва, че вашата сборка има такъв, затова двата теста трябва да се проведат отделно.
Отказите на доверие са заради името в сертификата
NSURLErrorServerCertificateUntrusted взето заедно с грешката TLS под него, означава, че веригата или проверката на идентичността се е провалила. Вътрешен CA трябва да бъде доверен на устройството, а сертификат, издаден за друго име на хост, остава грешен след каквато и да е пренастройка на мрежата. Ръководството за App Transport Security продължава да важи за тези връзки, зареждащи URL, и тунел около обикновена HTTP услуга не прави тази услуга сигурна от край до край.
Поправете идентичността или котвата на доверие и дръжте списъка с изключения празен. Цялостно изключение за произволно зареждане скрива отказа по време на разработка и го оставя на място за всеки потребител след това.
HTTP отказът принадлежи на приложението, не на мрежата
401 или 403 след завършено ръкостискане означава, че заявката е пристигнала и услугата я е отказала, така че остава въпросът за акаунт, аудитория на токена, обхват или ключ. Записвайте кода на състоянието и името на хоста, никога носещия токен или тялото на отговора. В този момент тунелът си върши работата и по-нататъшните мрежови промени само отлагат истинската поправка.
Таблицата е класификацията, която да държите до терминала: един ред за всеки отказ, който приложението наистина може да съобщи. Отпечатайте кода, преди да го прочетете, защото редът, който изберете, решава кой раздел ще отработите.
| Where it fails | What the app sees | First check |
|---|---|---|
| name resolution | NSURLErrorCannotFindHost (-1003) | resolve the fully qualified name from the device itself |
| no path, or no answer | NSURLErrorTimedOut (-1001) | is this bundle inside the per-app mapping, and is the service path allowed |
| TLS trust | NSURLErrorServerCertificateUntrusted (-1202) | does the certificate name match the host, and is the internal CA trusted |
| service refusal | HTTP 401 or 403 after a completed handshake | account, token audience, scope or key |
Всеки ред е по-евтин за тестване от реда под него и всеки изключва различен слой от същата заявка. Вървете надолу по таблицата, докато ред съвпадне, после спрете да променяте мрежата.