Creating LoginUser Page

The LoginUser page displays a login form and authenticates a user who tries to login. As described in authentication and authorization, the user's browser is automatically redirected to the LoginUser page when the user is attempting to access a privileged page, such as a user admin page.

The workflow of LoginUser is very similar to the Contact page:

  1. When a user accesses the LoginUser page, a login form is displayed;
  2. The user fills in the username and password and clicks on the "login" button;
  3. The LoginUser receives the "login" event and triggers the authentication sequence;
  4. If the user enters correct username and password, the system assigns him a valid identity and redirects his browser to the desired privileged page; If not, a "password invalid" message is displayed.

We create two files protected/pages/users/LoginUser.page and protected/pages/users/LoginUser.php to save the page template and page class, respectively.

Creating Page Template

Below we show the template for LoginUser. As we see, the page mainly contains a text box for collecting username and a text box for password. The username input is required, which is ensured by the TRequiredFieldValidator. The correctness of the password input is ensured by the TCustomValidator which invokes the page's validateUser() method when validation is performed. The page also has "login" button which invokes the page's loginButtonClicked() when it is clicked.

<%@ Title="My Blog - Login" %>

<com:TContent ID="Main">

<h1>Login</h1>

<span>Username:</span>
<com:TRequiredFieldValidator
    ControlToValidate="Username"
    ErrorMessage="Please provide your username."
    Display="Dynamic" />
<br/>
<com:TTextBox ID="Username" />

<br/>
<span>Password:</span>
<com:TCustomValidator
    ControlToValidate="Password"
    ErrorMessage="Your entered an invalid password."
    Display="Dynamic"
    OnServerValidate="validateUser" />
<br/>
<com:TTextBox ID="Password" TextMode="Password" />

<br/>
<com:TButton Text="Login" OnClick="loginButtonClicked" />

</com:TContent>

Creating Page Class

Like the Contact page, the LoginUser page also needs a class file which mainly contains the implementation of event handlers attached in the page template. Here, we need to implement two methods: validateUser() and loginButtonClicked(). In validateUser(), we use the auth manager to verify if the username and password are valid. If valid, the auth manager will automatically create a user session with appropriate user identity information.

class LoginUser extends TPage
{
    /**
     * Validates whether the username and password are correct.
     * This method responds to the TCustomValidator's OnServerValidate event.
     * @param mixed event sender
     * @param mixed event parameter
     */
    public function validateUser($sender,$param)
    {
        $authManager=$this->Application->getModule('auth');
        if(!$authManager->login($this->Username->Text,$this->Password->Text))
            $param->IsValid=false;  // tell the validator that validation fails
    }

    /**
     * Redirects the user's browser to appropriate URL if login succeeds.
     * This method responds to the login button's OnClick event.
     * @param mixed event sender
     * @param mixed event parameter
     */
    public function loginButtonClicked($sender,$param)
    {
        if($this->Page->IsValid)  // all validations succeed
        {
            // obtain the URL of the privileged page that the user wanted to visit originally
            $url=$this->Application->getModule('auth')->ReturnUrl;
            if(empty($url))  // the user accesses the login page directly
                $url=$this->Service->DefaultPageUrl;
            $this->Response->redirect($url);
        }
    }
}

Testing

So we have created the LoginUser page. We can test it by visiting the URL http://hostname/blog/index.php?page=users.LoginUser. Remember in the Creating Database subsection, we already created two user accounts (username/password): admin/demo and demo/demo. We can use them to test our login page.

Adding Login/Logout Links to Master

To provide a direct way for users to login and logout, we modify the MainLayout master control a bit. In particular, we add a "login" hyperlink which links to the LoginUser page. We also add a "logout" link button which logs out a user when it is clicked.

We modify the footer section of the MainLayout's template as follows. The visibility of "login" and "logout" is determined according to user's status. If the user is not logged in yet, i.e., $this->User->IsGuest is true, the "login" link is visible while the "logout" link is not; and vice versa.

<div id="footer">
<com:THyperLink Text="Login"
    NavigateUrl="<%= $this->Service->constructUrl('users.LoginUser') %>"
    Visible="<%= $this->User->IsGuest %>" />

<com:TLinkButton Text="Logout"
    OnClick="logoutButtonClicked"
    Visible="<%= !$this->User->IsGuest %>"
	CausesValidation="false" />

<br/>
<%= PRADO::poweredByPrado() %>
</div>

Since the "logout" button attaches its OnClick event with a method called logoutButtonClicked(), we need to modify the class file of MainLayout as well.

class MainLayout extends TTemplateControl
{
    /**
     * Logs out a user.
     * This method responds to the "logout" button's OnClick event.
     * @param mixed event sender
     * @param mixed event parameter
     */
    public function logoutButtonClicked($sender,$param)
    {
        $this->Application->getModule('auth')->logout();
        $url=$this->Service->constructUrl($this->Service->DefaultPage);
        $this->Response->redirect($url);
    }
}

Now if we visit any page of our blog system, we should see either a link at the bottom of the page. The link displays "Login" if we have not logged in yet and "Logout" if we have logged in. If we click on "Logout", the browser will be redirected to the homepage and "Login" is displayed meaning we have logged out.