چگونه یک 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 |
هر ردیف ارزانتر از ردیف زیرش آزموده میشود، و هر کدام لایه متفاوتی از همان درخواست را کنار میگذارد. جدول را پایین بروید تا ردیفی مطابق شود، بعد تغییر شبکه را متوقف کنید.