2012-06-14 11 views
10

हैंडलिंग मैं फोनगैप (उर्फ कॉर्डोवा) का उपयोग करके एक आईओएस एप्लिकेशन लिख रहा हूं, मेरे पास एक साधारण HTML लॉगिन पृष्ठ है जो उपयोगकर्ता को SSLHttpRequest का उपयोग SSL पर मूल प्रमाणीकरण के साथ लॉग इन करता है। जब आप अपना उपयोगकर्ता नाम और पासवर्ड सही ढंग से दर्ज करते हैं तो सब कुछ शानदार काम करता है। हालांकि, अगर आप गलत उपयोगकर्ता नाम/पासवर्ड दर्ज करते हैं तो मेरे किसी भी कॉलबैक को कभी भी बुलाया नहीं जाता है।आईओएस: XMLHttpRequest का उपयोग करके प्रमाणीकरण - 401 प्रतिकृति

यदि आप क्रोम पर एक ही कोड चलाते हैं, उदाहरण के लिए, गलत उपयोगकर्ता नाम/पासवर्ड के साथ, क्रोम एक समान तरीके से व्यवहार करता है, सिवाय इसके कि यह एक प्रमाणीकरण चुनौती संवाद पॉप अप करता है। क्रोम के संवाद पर रद्द करना मारना मेरे जावास्क्रिप्ट कोड पर नियंत्रण देता है। दुर्भाग्यवश, आईओएस पर, UIWebView भी एक ऑथ संवाद पॉप अप नहीं करेगा, यह बस लटकता है। मुझे उपयोगकर्ता को यह बताने का एक तरीका चाहिए कि उन्होंने गलत उपयोगकर्ता नाम या पासवर्ड दर्ज किया है ताकि वे पुनः प्रयास कर सकें।

मुझे यह जवाब मिल सकता है कि यह जवाब http://www.freelock.com/2008/06/technical-note-http-auth-with-ajax था लेकिन सर्वर से प्रतिक्रिया स्थिति बदलना सही काम जैसा प्रतीत नहीं होता है।

यहां मूल रूप से मेरा अनुरोध कोड कैसा दिखता है, लेकिन जब कोई खराब उपयोगकर्ता नाम या पासवर्ड भेजा जाता है तो यह कभी भी मेरे ऑनलोड कॉलबैक तक नहीं पहुंचता है (असल में पहले से ही बदले में कॉलबैक केवल एक बार बुलाया जाता है और तैयार चरण 1, उर्फ ​​ओपन) के लिए होता है।

var req = new XMLHttpRequest(); 
req.onload = function(ev) { 
    if (req.status == 401) { 
     alert("Invalid Username/Password"); 
     document.getElementById('password').focus(); 
    } else if (req.status == 200) { 
     window.location.href = some_secure_site; 
    } else { 
     // edit // 
     alert("Some other status"); 
    } 
} 
req.onerror = function (ev) { alert('Error'); }; 
req.ontimeout = function(ev) { alert('Timeout'); }; 
req.open('GET', uri, true, userValue, passValue); 
req.withCredentials = true; 
req.send(); 
+0

उस समस्या से संबंधित होने लगता है: https://issues.apache.org/jira/browse/CB-2415 कृपया इसे जल्द ही ठीक करने के लिए वोट दें – martinoss

उत्तर

3

आईओएस पर ऐसा करने की कोशिश करते समय कुछ चीजें मेरे लिए स्पष्ट हो गईं। एक यह है कि आईओएस में बुनियादी लेख से संबंधित एक बग है, इसलिए यदि आपके पासवर्ड में कुछ विशेष वर्ण हैं तो आपको कभी भी अपने सर्वर से प्रतिक्रिया नहीं मिलेगी क्योंकि आपके सर्वर को कभी भी प्रमाणीकरण चुनौती नहीं मिलेगी। यही है, यदि आप "खुली" विधि में उपयोगकर्ता नाम और पासवर्ड फ़ील्ड का उपयोग कर रहे हैं।

मेरा अनुमान है कि वे कुछ http माध्यम से भेज तरह बेवकूफ कर रहे है: // उपयोगकर्ता नाम: [email protected]/etc जब वे ऐसा

req.setRequestHeader("Authorization", "Basic " + base64(username) + ':' + base64(password)); 
तरह creds एन्कोडिंग का उपयोग करना चाहिए http हेडर और base64

दूसरी बात जो मैंने सीखा वह यह है कि बेसिक एथ बहुत सुरक्षित नहीं है और यह दस लाख और एक समस्या से ग्रस्त है। जिसमें से एक आपको परेशान करेगा कि ग्राहक उपयोगकर्ता नाम और पासवर्ड को कैश करेगा, जो आपके द्वारा भेजे गए किसी भी नए मान को "req.open (...)" के माध्यम से ओवरराइड करेगा। अकेले जावास्क्रिप्ट का उपयोग करके उसमें अच्छी किस्मत हो रही है, आपको कैश को साफ़ करने के लिए ओबीजेसी में कुछ जादू करना होगा।

यदि आपके सर्वर पर नियंत्रण है, तो मैं टोकन प्रमाणीकरण का उपयोग करने का सुझाव दूंगा। एसएसएल से कनेक्ट करें और फिर उपयोगकर्ता नाम और पासवर्ड वाले JSON डेटा के साथ एक पोस्ट भेजें। सर्वर फिर एक प्रमाणीकरण टोकन के साथ जेएसओएन डेटा वापस भेज सकता है (अनिवार्य रूप से यादृच्छिक वर्णों का एक समूह जो लंबे समय तक अनुमान लगाया जा सकता है, एक यूयूआईडी अच्छी तरह से काम करता है। यह सर्वर द्वारा उत्पन्न होता है और केवल ग्राहक को ही जाना जा सकता है और सर्वर)। फिर कुंजीपटल में टोकन और उपयोगकर्ता नाम स्टोर करें ताकि उपयोगकर्ता को अपना ऐप शुरू करने पर हर बार अपने क्रेडिट दर्ज करने की आवश्यकता न हो।

मेरा सर्वर हमेशा 200 प्रतिक्रिया वापस भेज देगा लेकिन JSON डेटा में या तो पुनः प्रयास करने या ऑथ टोकन को स्टोर करने के लिए आवश्यक जानकारी होगी। सामान्य रूप से ... मूल लेख मूल रूप से बेकार है।

try { 
    var req = new XMLHttpRequest(); 
    req.onload = function(ev) { 
     var response = JSON.parse(this.responseText); 
     if (response.success === true) { 
      // The server will respond with a token that will allow us to login 
      storeCredentials(userValue, response.token); 
      // redirect with token 
     else if (req.status == 401) { 
      alert("Invalid Username/Password"); 
      document.getElementById('password').focus(); 
     } else { 
      alert("Some other status"); 
     } 
    } 
    req.ontimeout = setTimeout(function(ev) { navigator.notification.alert('Timeout trying to contact the server'); }, 10000); 
    req.onerror = function(ev) { clearTimeout(this.ontimeout); navigator.notification.alert('Error connecting to the server during authentication.'); }; 

    var uri = myWebOrigin + '/authenticate'; 
    req.open('POST', uri, true); 
    req.setRequestHeader('Cache-Control', 'no-cache'); 
    req.setRequestHeader('Content-Type', 'application/json'); 
    json_data = {username : Base64.encode(userValue), password : Base64.encode(passValue)}; 
    req.send(JSON.stringify(json_data)); 
} catch(error) { 
    navigator.notification.alert('Uh oh, an error occurred trying to login! ' + error); 
    return; 
} 
+2

यदि उपयोगकर्ता नाम या पासवर्ड में विशेष वर्ण हैं तो आप encodeURIComponent (username) को कॉल करने का प्रयास कर सकते हैं। मुझे आईओएस + फोनगैप के साथ कोई समस्या थी, जहां इन वर्णों वाले निहित उपयोगकर्ता नाम या पासवर्ड विफल हो जाएंगे और उन्हें एन्कोडिंग करने के लिए इसे ठीक किया जाएगा। –

0

वहाँ प्राप्त 401 और 200 कोड बगल में शायद एक अन्य HTTP स्थिति कोड है! सुनिश्चित करें कि वास्तव में कोई अन्य स्थिति कोड प्राप्त हुआ है:।

if (req.status == 401) { 
    alert("Invalid Username/Password"); 
    document.getElementById('password').focus(); 
} else if (req.status == 200) { 
    window.location.href = some_secure_site; 
} else { 
    alert('Unfetched status code '+req.status+' captured!'); 
} 
+0

मेरे पास मेरे कोड में एक और विवरण है और दुर्भाग्यवश यह नहीं मिलता है कहा जाता है, मेरा ऑनलोड कॉलबैक कभी नहीं कहा जाता है। फिर, क्रोम में एक ही व्यवहार लेकिन क्रोम एक ऑथ संवाद प्रदर्शित करता है। ऑथ डायलॉग को रद्द करने से मेरा ऑनलोड कॉलबैक –

0

मैं एक ही समस्या हो रही किया गया है - अमान्य क्रेडेंशियल्स में पारित कर रहे हैं, तो अनुरोध पर कॉलबैक में से कोई भी कहा जा रहा है

मेरा अनुमान क्या आंतरिक रूप से UIWebView को क्रेडेंशियल्स के लिए संकेत देने के लिए कहा जा रहा है, लेकिन उस प्रॉम्प्ट को दबाया जा रहा है, जिससे इस बग का कारण बनता है। यह उन सभी अन्य ब्राउज़रों पर आधारित है जिन्हें मैंने कोशिश की है (सफारी, क्रोम, फ़ायरफ़ॉक्स) इस मामले में कॉलबैक को कॉल नहीं करते जब तक कि प्रॉम्प्ट को खारिज नहीं किया जाता है।

एक और समाधान (जिसे मैं उपयोग कर रहा हूं) प्रमाणीकरण करने के लिए जावास्क्रिप्ट का उपयोग नहीं करना होगा, और इसके बजाय इसे आईओएस पक्ष पर करें - आप How to display the Authentication Challenge in UIWebView? पर कोड का उपयोग करने के लिए किसी न किसी टेम्पलेट के रूप में उपयोग कर सकते हैं।

1

आईओएस + फोनगैप + jQuery का उपयोग करते समय मुझे कॉलबैक में से कोई भी कॉल नहीं किया गया था। अगर मैं गलत क्रेडेंशियल गुजरती हैं और का उपयोग

$.ajax({ 
    ... 
    timeout: 5000, // Some timeout value that makes sense 
    ... 
}); 

तो त्रुटि कॉलबैक {"readyState":0,"status":0,"statusText":"timeout"} साथ कहा जाता है। उस मामले में आप वैकल्पिक रूप से आप

$.ajax({ 
    ... 
    async: false, // :-(
    ... 
}); 

और अपने त्रुटि कॉलबैक का उपयोग कर सकते {"readyState":4,"responseText":"<html>...</html>","status":401,"statusText":"Unauthorized"} वापस की तरह कुछ मिल जाएगा लगता है कि वास्तविक त्रुटि HTTP 401

है होगा।

+0

ट्रिगर हो जाएगा, यह मेरे लिए काम करता है – Deviney

0

इस समस्या का समाधान करने के लिए सर्वर प्रतिक्रिया से हैडर WWW-Authenticate को हटा दें।

संबंधित मुद्दे