2011-05-23 11 views
5

का उपयोग करके स्कैला में लॉगिन/लॉगआउट फॉर्म बनाने का सबसे अच्छा तरीका है क्योंकि अधिक से अधिक लोग स्कैला (खुद की तरह) में रुचि रखते हैं, एक प्रश्न के बजाय, मैं लॉगिन/लॉगआउट स्निपेट के कार्यान्वयन पर चर्चा करना चाहता हूं लिफ्ट पर आधारित वेबपैप के लिए।लिफ्ट

मैंने अभी स्कैला और लिफ्ट सीखना शुरू किया है, तो शायद यह ऐसी सुविधा को लागू करने का सबसे अच्छा तरीका नहीं है, लेकिन मैं इसे अन्य शुरुआती लोगों के लिए साझा करना चाहता हूं और अधिक अनुभवी डेवलपर्स के साथ चर्चा करना चाहता हूं। कृपया ध्यान दें कि मैं वेब विकास में भी विशेषज्ञ नहीं हूं। सुधार के लिए किसी भी मदद बहुत सराहना की जाएगी (विशेष रूप से प्रदर्शन और सुरक्षा संबंधी वाले) ;-)

1) सबसे पहले, टुकड़ा आसानी से plugable होने के लिए, की जरूरत है अपने डिफ़ॉल्ट में कोड की 1 लाइन के साथ की तरह टेम्पलेट। मैंने इसे एम्बेडेड लिफ्ट सुविधा का उपयोग करके किया है (अंडरस्कोर को नोटिस करें, इसलिए इसे पृष्ठ के रूप में प्रस्तुत नहीं किया जा सकता है, लेकिन इसे किसी भी प्रकार के "निजी" स्निपेट में, केवल एक प्रस्तुत पृष्ठ से ही बुलाया जाता है):

<lift:embed what="_logInForm" /> 

2) फिर, _logInForm.html में, मैं नीचे मार्कअप और एक सशर्त प्रदर्शन का उपयोग सब कुछ संभाल करने के लिए:

<div> 
    <!-- User is not logged in, show a form to log in using the method loggedOut --> 
    <lift:LogInForm.loggedOut> 
     <form class="lift:LogInForm.logIn?form=post"> 
      <label for="textName">Username: </label><input type="text" id="textName" name="name" /> <span class="lift:Msg?id=name;errorClass=error"/><br/> 
      <label for="textPassword">Password: </label><input type="password" id="textPassword" name="password" /> <span class="lift:Msg?id=password;errorClass=error"/><br/> 
      <input type="submit" value="Log in" /> 
     </form> 
    </lift:LogInForm.loggedOut> 

    <!-- User is logged in, show who she is and a way to log out using the method loggedIn --> 
    <lift:LogInForm.loggedIn> 
     <form class="lift:LogInForm.logOut?form=post"> 
     Connected as <span class="lift:LogInForm.getName" />.<br /> 
     <input type="submit" id="btnLogOut" value="Log out" /> 
     </form> 
    </lift:LogInForm.loggedIn> 
</div> 

3) ... और अब स्काला/लिफ्ट टी के पीछे तर्क उसके मार्कअप:

object LogInForm { 
    private object name extends SessionVar("") 
    private object password extends RequestVar("") 
    private object referer extends RequestVar(S.referer openOr "/") 
    var isLoggedIn = false 

    def loggedIn(html: NodeSeq) = 
    if (isLoggedIn) html else NodeSeq.Empty 

    def loggedOut(html: NodeSeq) = 
    if (!isLoggedIn) html else NodeSeq.Empty 

    def logIn = { 
    def processLogIn() { 
     Validator.isValidName(name) match { 
     case true => { 
      Validator.isValidLogin(name, password) match { 
      case true => { isLoggedIn = true } // Success: logged in 
      case _ => S.error("password", "Invalid username/password!") 
      } 
     } 
     case _ => S.error("name", "Invalid username format!") 
     } 
    } 

    val r = referer.is 
    "name=name" #> SHtml.textElem(name) & 
     "name=password" #> (
     SHtml.textElem(password) ++ 
      SHtml.hidden(() => referer.set(r))) & 
     "type=submit" #> SHtml.onSubmitUnit(processLogIn) 
    } 

    def logOut = { 
    def processLogOut() { isLoggedIn = false } 
    val r = referer.is 
    "type=submit" #> SHtml.onSubmitUnit(processLogOut) 
    } 

    def getName = "*" #> name.is 
} 

टिप्पणियाँ:

  • दो रूपों के बीच चयन तथ्य पर आधारित तर्क के आधार पर किया जाता है, प्रतिपादन या तो प्रदान की मार्कअप या NodeSeq.Empty, उपयोगकर्ता या तो है लॉग इन या लॉग आउट
  • मैंने लिफ्ट का उपयोग किया: संदेश उचित फ़ील्ड (नाम/पासवर्ड) के आगे त्रुटि संदेश प्राप्त करने के लिए। संदेश का उपयोग करके भेजा गया है। आतंक तर्क के पीछे तर्क और उचित आईडी में भेजा गया है।
  • मैं वास्तव में रेगेक्स और प्रारूप चेक आदि का उपयोग करके एक वैलिडेटर सहायक में चेक करता हूं। यह प्रत्येक बार पैटर्न मिलान के लिए एक बुलियन लौटता है।
  • मैं रेफरर का उपयोग करता हूं ताकि उपयोगकर्ता उसी पृष्ठ पर रहने के दौरान लॉग इन/लॉग आउट कर सकें।
  • उपयोगकर्ता नाम एक सत्र चर के रूप में रखा जाता है और दिखाया जाता है जब में लॉग इन

4) आप Boot.scala में निम्न कार्य अन्य पन्नों तक पहुँच को नियंत्रित कर सकते हैं:।

def sitemap() = SiteMap(
     Menu("Home")/"index", 
     Menu("Protected page")/"protectedPageName" >> If(() => LogInForm.isLoggedIn, ""), 
     // etc. 

सवाल:

  1. कोई एसएसएल सुरक्षा (यह एक सुधार हो सकता है, अभी तक स्कैला/लिफ्ट में इसे नहीं देखा है)। किसी और से कोई अनुभव उपयोगी हो सकता है?
  2. सत्र चर का उपयोग करें। शायद स्काला/लिफ्ट में राज्य को रखने का एक बेहतर तरीका है?
  3. क्या पहले से ही कुछ ऐसा है जो विशेष रूप से लिफ्ट में में लॉग इन करने के लिए बनाया गया था जिसे मैं याद कर सकता था?
  4. यह बहुत लंबा नहीं है, लेकिन शायद कॉम्पैक्ट हो सकता है? (हालांकि मैं बहुत अधिक पठनीयता बलिदान नहीं करना चाहता हूं। अन्य डेवलपर्स को इसे तुरंत समझने की आवश्यकता है)
  5. कोई अन्य सुझाव?

चीयर्स,

मार्क।

+1

आप इसका जिक्र नहीं करते हैं, लेकिन क्या आपने लिफ्ट में प्रोटोयूसर/मेगाप्रोटो यूज़र कोड देखा है? – Debilski

उत्तर

2
  1. इससे पता चलता है, आप आमतौर पर उपयोग करेगा जिसे प्रवेश फार्म पेज मेनू के लिए कैसे SSL के उपयोग को मजबूर करने के लिए: Lift filter to force ssl
  2. एक सत्र चर आम तौर पर सबसे अच्छा तरीका सत्र जानकारी रखने के लिए
  3. ProtoUser है (यदि आप उपयोग कर सकते हैं उदाहरण के रूप में लॉगिन के साथ एक परियोजना स्थापित करने के लिए लिफ्टी (http://lifty.github.com/)
2

लिफ्ट इन उपयोगकाइयों के लिए एक मचान ढांचा प्रदान करता है। आप net.liftweb.proto.ProtoUser के स्रोत कोड पर एक नज़र रखना चाहते हैं। खासकर login() और loginXhtml

लिफ्ट के बुनियादी उदाहरण यह निम्नलिखित तरीके से करना:

  1. आप परिभाषित करने के बाद अपने बूट में सब बुरा लिफ्ट कोड

    package yourcompany.model 
    
    import net.liftweb.mapper._ 
    import net.liftweb.util._ 
    import net.liftweb.common._ 
    
    class User extends MegaProtoUser[User] { 
        // your code, mostly overrides 
    
    } 
    
    object User extends User with MetaMegaProtoUser[User] { 
        override def dbTableName = "users" 
        // other database related code 
    } 
    
  2. का उपयोग करता है एक स्वयं मैप किया गया उपयोगकर्ता वर्ग अपना साइटमैप, निम्न कार्य करें:

    // do not forget to import your user 
    def sitemap() = Sitemap(Menu("Home")/"index" >> User.AddUserMenusAfter) 
    
    // now comes the magic 
    LiftRules.setSiteMap(User.sitemapMutator(sitemap())) 
    

इसमें आपके पृष्ठ पर कई लिंक शामिल होंगे, सभी /user_mgt के तहत एकत्र हुए हैं। sign_up, login, lost_password। मेरे लिए यह काम करने के लिए एक महान आधार है। आप ProtoUser में होने वाली लगभग सभी चीजों को ओवरराइड कर सकते हैं, या बस अच्छी बिट्स कॉपी कर सकते हैं और सब कुछ लागू कर सकते हैं।

अगर किसी के पास अतिरिक्त दस्तावेज़ हैं, तो यह बहुत उपयोगी होगा। फिलहाल मैं स्रोतों का उपयोग करके सबसे अधिक हिस्सा निकालने का प्रयास करता हूं।

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