Login
It is a common way to request an account and a password for
authentication. We create a login page to collect user's account and
password, and the login page also uses a template zul to keep a
consistent style with the index page. However, there should be no sidebar because users without logging in should not be able to access main functions. So we need to change our template to create the sidebar according to user credential in the session with a shadow component, <if>
.
chapter7/layout/template.zul
<zk>
<borderlayout hflex="1" vflex="1" >
<north height="100px" border="none" >
<apply templateURI="/chapter7/layout/banner.zul"/>
</north>
<!-- create only when the currentUser is not an anonymous -->
<if test="${not sessionScope.userCredential.anonymous}">
<west width="260px" border="none" collapsible="true" splittable="true" minsize="300">
<apply templateURI="/chapter6/ajaxbased/sidebar.zul"/>
</west>
</if>
<center id="mainContent" autoscroll="true" border="none">
<!-- the main content will be insert to here -->
<apply template="center"/>
</center>
<south height="50px" border="none">
<apply templateURI="/chapter1/footer.zul"/>
</south>
</borderlayout>
</zk>
- Line 7: Determine if there is an anonymous user credential in the session by EL.
The login form is built with Grid. This page should be accessible for
all users, so we don't have to apply AuthenticationInit
.
chapter7/login.zul
<?link rel="stylesheet" type="text/css" href="/style.css"?>
<zk>
<div height="100%">
<template name="layout" src="/chapter7/layout/template.zul"/>
<apply template="layout"/>
<template name="center">
<hbox vflex="1" hflex="1" align="center"
pack="center" spacing="20px">
<vlayout>
<window id="loginWin"
apply="org.zkoss.essentials.chapter7.LoginController"
title="Login with you name" border="normal" hflex="min">
<vbox hflex="min" align="center">
<grid hflex="min">
<columns>
<column hflex="min" align="right" />
<column />
</columns>
<rows>
<row>
Account :
<textbox id="account" width="200px" />
</row>
<row>
Password :
<textbox id="password" type="password"
width="200px" />
</row>
</rows>
</grid>
<label id="message" sclass="warn" value=" " />
<button id="login" label="Login" />
</vbox>
</window>
(use account='zkoss' and password='1234' to login)
</vlayout>
</hbox>
</template>
</div>
</zk>
- Line 6: Define a template named
cetner
which is used intemplate.zul
. - Line 26: Specify "password" at
type
, then user input will be masked.
This login controller collects the account and password and validates them with an authentication service class. If the password is correct, the authentication service class saves user's credentials into the session.
Controller used in chapter7/login.zul
public class LoginController extends SelectorComposer<Component> {
//wire components
@Wire
Textbox account;
@Wire
Textbox password;
@Wire
Label message;
//services
AuthenticationService authService = new AuthenticationServiceChapter7Impl();
@Listen("onClick=#login; onOK=#loginWin")
public void doLogin(){
String nm = account.getValue();
String pd = password.getValue();
if(!authService.login(nm,pd)){
message.setValue("account or password are not correct.");
return;
}
UserCredential cre= authService.getUserCredential();
message.setValue("Welcome, "+cre.getName());
message.setSclass("");
Executions.sendRedirect("/chapter7/");
}
}
- Line 20: Authenticate a user with account and password and save user's credential into the session if it passes.
- Line 28: Redirect to index page after successfully authenticated.
After login, we want to display a user's account in the banner. We can
use EL to get a user's account from UserCredential
in the session.
chapter7/layout/banner.zul
<div hflex="1" vflex="1" sclass="banner">
<hbox hflex="1" vflex="1" align="center">
<!-- other components -->
<hbox apply="org.zkoss.essentials.chapter7.LogoutController"
hflex="1" vflex="1" pack="end" align="end" >
<label value="${sessionScope.userCredential.name}"
if="${not sessionScope.userCredential.anonymous}"/>
<label id="logout" value="Logout"
if="${not sessionScope.userCredential.anonymous}" sclass="logout"/>
</hbox>
</hbox>
</div>
- Line 7: The sessionScope/sessionScope)
is an implicit object that you can use within EL to access session's
attribute. It works as the same as
getAttribute()
. You can use it to get session's attribute with dot notation, e.g.${sessionScope.userCredential}
equals to callinggetAttribute("userCredential")
of aSession
object.