As more and more people are interested in Scala (like me), and not a question, I would like to discuss one implementation of the Lift-based webapp login / logout fragment .
I just started to learn Scala and Lift, so it may not be the best way to implement such a function, but I would like to share it with other beginners and discuss it with more experienced developers.Please note that I am also not a specialist in web development . Any help for improvements would be greatly appreciated (especially in terms of performance and security); -)
1) First of all, the fragment should be easily connected, for example, with 1 line of code in the default template. I did this using the built-in Elevator function (pay attention to underlining so that it does not appear as the page itself, but is called only from the displayed page, in short, some kind of "private" fragment):
<lift:embed what="_logInForm" />
2) Then, in _logInForm.html, I use the markup below and the conditional display to handle everything:
<div>
<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>
<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) ... and now the Scala / Lift logic behind this markup:
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 }
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
}
Comments:
- , , NodeSeq.Empty, , , .
- : Msg, (/). S.error id.
- Validator, .. , .
- referer, / , .
- .
4) , Boot.scala:
def sitemap() = SiteMap(
Menu("Home") / "index",
Menu("Protected page") / "protectedPageName" >> If(() => LogInForm.isLoggedIn, ""),
// etc.
:
- SSL ( , Scala/Lift). - ?
- . , Scala/Lift?
- - / Lift, ?
- , ? ( . )
- ?
,
.