Expo ऐप Android 9 पर HTTP में विफल: कारण cleartext है, VPN नहीं
सादे HTTP API को कॉल करने वाला Expo बिल्ड Android 9 और उसके बाद विफल होता है। टनल निर्दोष है: cleartext फ़्लैग बिल्ड कॉन्फ़िग में होना चाहिए।
आपने नया बिल्ड जारी किया, VPN पर गए, और वही स्क्रीन लोड होना बंद हो गई। Android 9 और उसके बाद अधिक आम व्याख्या अधिक नीरस है: प्लेटफ़ॉर्म API 28 या उससे ऊपर लक्ष्य करने वाले ऐप्स के लिए सादा HTTP अस्वीकार करता है, और VPN ने केवल इतना संदर्भ बदला कि यह सामने आ जाए। आपको जो त्रुटि दिखती है वह HTTP क्लाइंट पर निर्भर करती है, इसलिए वह इतनी कम बार cleartext कहती है।
यह विफलता वास्तव में क्या है
Android 9 से प्लेटफ़ॉर्म डिफ़ॉल्ट रूप से cleartext ब्लॉक करता है, जैसे ही ऐप API स्तर 28 या उससे ऊपर लक्ष्य करता है। प्लेटफ़ॉर्म सादे HTTP पते के अनुरोध को अस्वीकार कर देता है, इससे पहले कि एक भी पैकेट डिवाइस से निकले। आप कौन-सी त्रुटि देखते हैं यह HTTP लाइब्रेरी पर निर्भर करता है: कभी सामान्य नेटवर्क विफलता, कभी समय-समाप्ति, कभी ऐसा संदेश जो cleartext को सीधे नाम देता है। जो यह कभी नहीं करता वह है आपके सर्वर तक पहुँचना। Android डिफ़ॉल्ट और डोमेन-सीमित विकल्प को अपनी सुरक्षा कॉन्फ़िगरेशन गाइड में दस्तावेज़ित करता है।
उसी डिवाइस का ब्राउज़र अभी भी पेज लोड कर सकता है, और यही वह सुराग है जिसे ज़्यादातर लोग चूक जाते हैं। ब्राउज़र आपके ऐप की नेटवर्क सुरक्षा नीति के अधीन नहीं हैं।
VPN पर दोष क्यों आता है
आम तौर पर तीन चीज़ें एक साथ बदलती हैं। VPN जुड़ने के बाद ऐप किसी दूसरे होस्टनाम को रिज़ॉल्व कर सकता है, डिवाइस नया और नए बिल्ड वाला हो सकता है, या बिल्ड ही ऐसे लक्ष्य API स्तर पर चला गया हो जो डिफ़ॉल्ट सक्रिय करता है। VPN दिखता है और लक्ष्य SDK नहीं, इसलिए टिकट VPN को मिलता है।
नेटवर्क कॉन्फ़िग छूने से पहले पुराने और नए बिल्ड के लक्ष्य स्तरों की तुलना करें। 27 या उससे नीचे लक्ष्य करने वाला ऐप छूट प्राप्त है, और यही «मेरे पुराने फ़ोन पर चलता है» जैसी हर रिपोर्ट को समझाता है।
Expo फ़्लैग वास्तव में कहाँ पड़ता है
प्रबंधित Expo प्रोजेक्ट में app.json में सेटिंग जोड़ने से Android मैनिफ़ेस्ट संपादित नहीं होता, क्योंकि मैनिफ़ेस्ट prebuild और डेवलपमेंट बिल्ड बनाते हैं। उस चरण में सेटिंग कॉन्फ़िग प्लगइन लिखता है। समर्थित रास्ता expo-build-properties है, जो ऐप कॉन्फ़िग में android के अंतर्गत cleartext विकल्प के साथ कॉन्फ़िगर होता है।
{
"plugins": [
["expo-build-properties", {
"android": { "usesCleartextTraffic": true }
}]
]
}स्निपेट केवल प्लगइन विकल्प सेट करता है; मैनिफ़ेस्ट बाद में बनता है। prebuild या नया डेवलपमेंट-क्लाइंट बिल्ड चलाएँ, फिर दोबारा परीक्षण से पहले बने AndroidManifest.xml में android:usesCleartextTraffic जाँचें, क्योंकि केवल JS रीलोड पुराना मैनिफ़ेस्ट बनाए रखता है। प्लगइन संस्करण को उस Expo SDK से मिलाएँ जिस पर प्रोजेक्ट चलता है। प्लगइन विकल्प रिलीज़ के बीच बदलते हैं, और दूसरे SDK से कॉपी किया गया स्निपेट शांत निष्क्रियता का भरोसेमंद स्रोत है।
Bare वर्कफ़्लो और अधिक संकीर्ण विकल्प
bare React Native के लिए समतुल्य है application एलिमेंट पर android:usesCleartextTraffic, या ऐसा नेटवर्क सुरक्षा कॉन्फ़िग जो केवल नामित डोमेन के लिए cleartext की अनुमति दे। डोमेन-सीमित रूप ही पसंद किया जाना चाहिए, क्योंकि यह आंतरिक API की अनुमति देता है और बाकी सब HTTPS पर छोड़ देता है। यह अपनी अपवाद सूची भी दस्तावेज़ित करता है, और समीक्षक ठीक उसी हिस्से के बारे में पूछेगा।
दोनों में से कोई भी दृष्टिकोण उस किसी चीज़ के लिए प्लेटफ़ॉर्म का डिफ़ॉल्ट नहीं बदलता जिसका आपने नाम नहीं लिया।
पहले डिवाइस लॉग से साबित करें
कॉन्फ़िग संपादित करने से पहले सटीक विफलता पाएँ। जुड़े डिवाइस पर adb logcat प्लेटफ़ॉर्म का cleartext अस्वीकार दिखाता है और उस घटक का नाम बताता है जिसने इसे उठाया। अस्वीकृत सॉकेट, रिज़ॉल्व न होने वाला नाम या विफल TLS हैंडशेक पूरी तरह कहीं और इशारा करते हैं, और cleartext सक्षम करना ऐप को बेकार में कमज़ोर ही करेगा।
फिर प्रोडक्शन को ईमानदार रखें। जो लैब एंडपॉइंट TLS नहीं दे सकता उसके लिए cleartext स्वीकार्य है, और केवल उतने ही कम समय के लिए जितना आप योजना बना सकें। यदि API निजी नेटवर्क के भीतर TLS समाप्त कर सकता है, तो प्रमाणपत्र को डिवाइस के ट्रस्ट स्टोर में रखें और cleartext बंद रखें, क्योंकि टनल अपने निकास तक का रास्ता एन्क्रिप्ट करती है और उसके आगे कुछ नहीं।
एक बार एंडपॉइंट HTTPS पर उत्तर देने लगे, तो अनुमति हटाएँ, फिर से बिल्ड करें और उसी सत्र में VPN पर और सामान्य Wi-Fi पर परीक्षण करें। नाम रिज़ॉल्यूशन इन दो रास्तों में अलग हो सकता है, और केवल यही जोड़ी बताती है कि कौन सच कह रहा है।