2012-09-27 12 views
6

चलाएं मैं दूरस्थ प्रमाणीकरण सेवा के माध्यम से उपयोगकर्ताओं को प्रमाणित करने का प्रयास कर रहा हूं। मैं सेवा करने के लिए संदेश भेजने और परिणाम के लिए इंतजार के लिए सहायक विधि लिखा है:2 फॉर्म सीमा

def authenticateAwait(email:  String, 
         password: String 
        ): Either[String, Option[User]] = { 
    try { 
    val future = authenticate(email, password) 
    Right(Await.result(future, timeout.duration)) 
    } catch { 
    case _ ⇒ Left("Unable to connect to authentication server") 
    } 
} 

यह एक त्रुटि विवरण के साथ Left[String] लौटाता है यदि संदेश नहीं भेजा जा सकता है, या वहाँ कोई जवाब नहीं है। अगर सेवा प्रतिक्रिया प्राप्त हुई, तो यह Right[Option[User]] लौटाता है। प्रमाणीकरण परिणाम के आधार पर सेवा Option[User] के साथ प्रतिक्रिया देती है।

सत्यापनकर्ता के एक जोड़े के साथ वास्तविक प्रमाणीकरण मैं प्रपत्र बना लिया है करने के लिए, यहाँ यह है:

val loginForm = Form(
 tuple(
    "email"    → email, 
    "password" → nonEmptyText 
) verifying ("Invalid email or password", result => result match { 
    case (email, password) ⇒ 
     User.authenticateAwait(email, password) match { 
     case Left(_) ⇒ true 
     case Right(optUser) ⇒ optUser.isDefined 
     } 
    }) verifying ("Unable to connect to authentication server", result => result match { 
    case (email, password) ⇒ 
     User.authenticateAwait(email, password) match { 
     case Left(_) ⇒ false 
     case Right(optUser) ⇒ true 
     } 
    }) 
) 

एक बात मुझे इस कोड के बारे में चिंता है, यह authenticateAwait दो बार कहता है। इसका मतलब है कि प्रति दो मान्यताओं को केवल दो संदेश भेजे जाएंगे। मुझे वास्तव में क्या चाहिए, authenticateAwait पर कॉल करना, परिणाम संग्रह करना और उस पर विभिन्न सत्यापन करना है। ऐसा लगता है कि कोई आसान समाधान नहीं है।

प्रमाणीकरण करने के लिए, आवश्यक फ़ील्ड फ़ील्ड तक पहुंचने के लिए, इसका मतलब है कि फ़ॉर्म को बाध्य किया जाना चाहिए और फिर मान्य किया जाना चाहिए, लेकिन मौजूदा रूप में त्रुटियों को संलग्न करने का कोई तरीका नहीं है (क्या मैं गलत हूं?)।

केवल इसकी रचना के दौरान त्रुटियों से त्रुटियों को जोड़ा जा सकता है, इसलिए मुझे वैधताओं में प्रमाणीकरण करना चाहिए, लेकिन फिर उपरोक्त समस्या होती है।

मेरे साथ आया एक अस्थायी समाधान एक विधि और var इसके अंदर परिभाषित करना है।

def loginForm = { 
    var authResponse: Either[String, Option[commons.User]] = null 

    Form(
    tuple(
     "email" → email, 
     "password" → nonEmptyText 
    ) verifying ("Invalid email or password", result ⇒ result match { 
     case (email, password) ⇒ 
     authResponse = User.authenticateAwait(email, password) 
     authResponse match { 
      case Left(_) ⇒ true 
      case Right(optUser) ⇒ optUser.isDefined 
     } 
    }) verifying ("Unable to connect to authentication server", result ⇒ result match { 
     case (email, password) ⇒ 
     authResponse match { 
      case Left(_) ⇒ false 
      case Right(optUser) ⇒ true 
     } 
    }) 
) 
} 

यह स्पष्ट रूप से एक हैक है। क्या कोई बेहतर समाधान है?

अद्यतन: मेरी राय में, फ़ॉर्म केवल इनपुट को स्वच्छ करना चाहिए, लेकिन प्रमाणीकरण फॉर्म के बाहर बाद में किया जाना चाहिए। समस्या यह है कि Form के हिस्से के रूप में दृश्य को त्रुटियों को भेजा जाता है और मौजूदा फ़ॉर्म में त्रुटियों को संलग्न करना असंभव है। त्रुटियों के साथ भी नया फॉर्म बनाने का कोई आसान तरीका नहीं है।

+1

इसे AJAX कहा जाता है; इसका उपयोग करें और आप ऐसी समस्या को हल करने की कोशिश कर रहे विशाल कोड ब्लॉक नहीं बनाएंगे जो मौजूद नहीं हैं (संकेत: नया फॉर्म बनाने की कोई आवश्यकता नहीं है) – virtualeyes

उत्तर

3

आपको क्या समझना है कि फ़ॉर्म अपरिवर्तनीय है। लेकिन त्रुटियों के साथ एक नया रूप बनाने के लिए उपयोगिता विधि का उपयोग करना आसान है:

loginForm.copy(errors = Seq(FormError("email", "Already registered"))) 
0

निश्चित रूप से, प्रमाणीकरण के साथ प्रमाणीकरण को भंग करने से बस एक सरल ऑपरेशन कॉम्प्लेक्स बन जाता है। नीचे अनचाहे है, लेकिन यह वह दिशा है जिसमें मैं जाऊंगा, समझ के लिए सही अनुमान लगाया गया है।

// point of validation is to sanitize inputs last I checked 
val form = Form(tuple("email"→ email, "password"→ nonEmptyText) 
val res = for{ 
    case(e,p) <- form.bindFromRequest.toRight("Invalid email or password") 
    success <- User.authenticateAwait(e,p).right 
} yield success 
res fold(Conflict(Left(_)), u=> Ok(Right(u))) 
+0

प्ले नमूने में फॉर्म सत्यापित करने के अंदर प्रमाणीकरण होता है, इसलिए सत्यापनकर्ता एक तरीका है जाना। आपके समाधान के बाद, यदि प्रमाणीकरण विफल रहता है, तो मुझे टेम्पलेट पर वापस त्रुटि के साथ फ़ॉर्म कैसे वापस करना चाहिए? – lambdas

+0

यह पहले से ही ऐसा कर रहा है, वाम में या तो फॉर्म सत्यापन त्रुटि, या कनेक्शन त्रुटि है; सही उपयोगकर्ता को स्पष्ट रूप से शामिल है ... वैसे भी, इसे एक परिणाम, संघर्ष (बाएं (_)) में लपेटें, u => ठीक है (दाएं (यू)) – virtualeyes

+0

भी, मुझे लगता है कि आप वायदा मार्ग ले रहे हैं , वह प्रदर्शन महत्वपूर्ण है; जैसे, एक मानक वेब ऐप में।AJAX जाने का रास्ता होगा, आईएमओ - इस तरह त्रुटि पर फॉर्म को फिर से प्रदर्शित करने की कोई आवश्यकता नहीं है, उपयोगकर्ता कभी भी कहीं नहीं जाता है, आप केवल त्रुटि की स्थिति से निपटते हैं और इसे प्रदर्शित करते हैं, या सफलता वापस करते हैं और तदनुसार संभालते हैं। – virtualeyes

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