Authentication

The TreeFrog Framework provides a simple authentication mechanism. In order to implement authentication, you need to create a model class that represents "user".
In this case, let's create a User class with the properties of a user name and password only. Defines the table as follows.

 > CREATE TABLE user ( username VARCHAR(128) PRIMARY KEY, password VARCHAR(128) );

 
Then go to the application root directory, create a model class with the command generator.

 $ tspawn usermodel user
   created  models/sqlobjects/userobject.h
   created  models/user.h
   created  models/user.cpp
   created  models/models.pro

 
User model class that inherits from class TAbstractUser is created by the "usermodel" option.
Field names that correspond to user name and password of a user model class are each "username" and "password" by default. You can also change as follow.
If you define each "user_id" and  "pass" in the DB schema, generate a class with the following command generator.

 $ tspawn usermodel user user_id pass

 
Unlike regular classes as models, the user model class has been added to authenticate method.
This method executes to authenticate as the name implies, which reads the User object with the key the user name and password,  and compare, to return the model object if they match.

User User::authenticate(const QString &username, const QString &password)
{
    if (username.isEmpty() || password.isEmpty())
        return User();

    TSqlORMapper<UserObject> mapper;
    UserObject obj = mapper.findFirst(TCriteria(UserObject::Username, username));
    if (obj.isNull() || obj.password != password) {
        obj.clear();
    }
    return User(obj);
}

 
This is a just sample code. You can modify it.

Login

Let's create a controller for the login/logout process, named as AccountController. It is provided with form, login and logout actions.

 > tspawn controller account form login logout
   created  controllers/accountcontroller.h
   created  controllers/accountcontroller.cpp
   created  controllers/controllers.pro

 
Skeleton code has been generated.
The form action shows Login Form.

void AccountController::form()
{
    render();   // shows form view
}

 
Create view/account/form.erb file as the form view, as follows.

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
</head>
<body>
  <h1>Login Form</h1>
  <div style="color: red;"><%==$message %></div>
  <%== formTag(urla("login")); %>
    <div>
      User Name: <input type="text" name="username" value="" />
    </div>
    <div>
      Password: <input type="password" name="password" value="" />
    </div>
    <div>
      <input type="submit" value="Login" />
    </div>
  </form>
</body>
</html>

 
In the login action, write the authentication process by using the user name and password of POST data.
When authentication is successful, let the user log into the system by calling the userLogin
method.

void AccountController::login()
{
    QString username = httpRequest().formItemValue("username");
    QString password = httpRequest().formItemValue("password");
 
    User user = User::authenticate(username, password);
    if (!user.isNull()) {
        userLogin(&user);
        redirect(QUrl(...));
    } else {
        QString message = "Login failed";
        texport(message);
        render("form");
    }
}

 Include "user.h" file.

Logout

To log out, call the userLogout method in the action.

void AccountController::logout()
{
  userLogout();
  redirect(url("Account", "form"));
}

 

Check logging in

To protect access from users who are not logged in, you can write down filter processing code in the preFilter method.

 bool HogeController::preFilter()
 {
     if (!isUserLoggedIn()) {
         redirect( ... );
         return false;
     }
     return true;
 }

 
If the preFilter method returns false, the action is not executed.
If you want to protect access to many controllers, write it into preFileter method of ApplicationController class.
 

Comments are closed.