Webiness

- build fast and secure web applications in short time -

User authentication and authorization are required for a Web page that should be limited to certain users.

Authentication is about verifying whether someone is who they claim to be. That, for instance, involve a user email address and password.

Authorization is finding out if the person, once identified (i.e. authenticated), is permitted to manipulate specific resources. This is usually determined by finding out if that person is of a particular role that has access to the resources.

Webiness has integrated user authentication and authorization system which features:
  1. WsAuth class which handles user login, logout, creation of new accounts, cheking permissions of current user, ...
  2. registration form for new users
  3. administration interface for user accounts
  4. administration interface for role based access (RBAC) managment

1. the basic principles

Integrated authentication and authorization system, to be functional, need to have access to database server. How to configure database access is explained in our basic guide.

For accessing administration interfaces, webiness uses special user account. Email address for that account is defined in protected/config/config.php file, with option auth_admin.
            
                // site administrators email address - needed for WsAuth
                WsConfig::set('auth_admin', 'your_name@your_domain');
            
        
Change that code in the way that you put valid email address there. Default password for selected email address would be set to admin. When you login with selected email address, which will be explained later, you will always have all grants and also you will never be able to delete that account from framework it self.

When you run first call to WsAuth class in your code, it will create all necessary tables in database and it will add admin user as it's described above. Internaly in database server, created tables will have prefix ws_.

2. checking is user logged in and get basic user informations

First thing that we would like to do with our authentication module is check if any user is currently logged in session. To do that, we will use public method checkSession() from WsAuth class. For example we may want to allow access to specific controller action only for registrated users:
            

                class ExpenseController extends WsController
                {
                    public $auth;

                    public function __construct()
                    {
                        parent::__construct();
                        // initialize user authentication
                        $this->auth = new WsAuth();
                    }


                    /*
                    .
                    .
                    more code here
                    .
                    .
                    */


                    public function expense_report()
                    {
                        // only loggedin users may access to this action
                        if (!$this->auth->checkSession()) {
                            trigger_error('Access Forbiden', E_USER_ERROR);
                            return;
                        }

                        // view response to registrated users
                        $this->render('expense_report');
                    }
                }
            
        
You can retrive id and email address of current logged in user using public methods currentUserID() and currentUser():
            
                // initilaize auth object (if it's not initialized before)
                $auth = new WsAuth();

                if ($auth->checkSession()) {
                    // get user ID
                    $id = $auth->currentUserID();
                    // get user email address
                    $email = $auth->currentUser();

                    echo 'user with email address: '.$email.' has ID: '.$id.PHP_EOL;
                }
            
        

3. register, login, edit and logout

Webiness has builtin actions for user registration, user login, edit account details and logout. You can create links to them by adding something like this to your view:
            
                <!-- link to registration form -->
                <a href="<?php echo WsUrl::link('wsauth', 'register'); ?>">
                    register new user
                </a>

                <!-- link to login form -->
                <a href="<?php echo WsUrl::link('wsauth', 'login'); ?>">
                    login
                </a>

                <!-- link to edit form -->
                <a href="<?php echo WsUrl::link('wsauth', 'edit'); ?>">
                    edit account details for current user
                </a>

                <!-- logout link -->
                <a href="<?php echo WsUrl::link('wsauth', 'logout'); ?>">
                    logout current user
                </a>
            
        

register form

login form

When registration process is activated, it will send verification mail to entered email address. New user will not be abble to login until it clicks on verification link in that message. If, for any reason, server is unable to send mail, then admin user must activate account manualy. How to do that will be axplain in the next chapter.

After successful login and logout you will be redirected to site/index page.

In most cases you will wish to add login and logout links to right side of page navigation bar. To make this even fancier we will show register and login link if there is no logged in user. If we have current user then show link his/her email address which will open account settings and in submenu show logout link. Open your layout file (by default it is: public/layouts/webiness.php) and add next code:
            
                <!-- HEADER -->
                <div class="row">
                <!-- original code in default layout -->
                    <div class="column column-8 column-offset-2 ws-header">
                        <label for="show-menu" class="show-menu">
                            <?php echo WsConfig::get('app_name'); ?>
                        </label>
                        <input type="checkbox" id="show-menu" role="button">
                        <!-- LEFT NAVIGATION BLOCK -->
                        <ul>
                            <li>
                                <a href="<?php echo WsUrl::link('site','index'); ?>">
                                    index
                                </a>
                            </li>
                        </ul>
                        <!-- END OF LEFT NAVIGATION BLOCK -->
                <!-- end of original code in default layout -->

                        <!-- this is our added code -->
                        <ul class="right">
                        <?php
                            if ($auth->checkSession()) {
                            ?>
                            <li class="right">
                                <a href="<?php echo WsUrl::link('wsauth','edit') ?>">
                                    <?php echo $auth->currentUser() ?>
                                </a>
                                <ul>
                                    <li>
                                        <a href="<?php echo WsUrl::link('wsauth','logout') ?>">
                                            <?php echo WsLocalize::msg('logout') ?>
                                        </a>
                                    </li>
                                    <?php
                                    if ($auth->hasPermission('admin') != true) {
                                    ?>
                                    <li>
                                        <a href="<?php echo WsUrl::link('wsauth','admin') ?>">
                                            <?php echo WsLocalize::msg('User Accounts') ?>
                                        </a>
                                    </li>
                                    <li>
                                        <a href="<?php echo WsUrl::link('wsauth','userRoles') ?>">
                                            <?php echo WsLocalize::msg('User Roles') ?>
                                        </a>
                                    </li>
                                    <li>
                                        <a href="<?php echo WsUrl::link('wsauth','rolePerms') ?>">
                                            <?php echo WsLocalize::msg('Role Permissions') ?>
                                        </a>
                                    </li>
                                    <?php
                                    }
                                    ?>
                                </ul>
                            </li>
                            <?php
                            } else {
                            ?>
                            <li class="right">
                                <a href="<?php echo WsUrl::link('wsauth','login') ?>">
                                    <?php echo WsLocalize::msg('login') ?>
                                </a>
                            </li>
                            <li class="right">
                                <a href="<?php echo WsUrl::link('wsauth','register') ?>">
                                    <?php echo WsLocalize::msg('register') ?>
                                </a>
                            </li>
                            <?php
                            }
                            ?>
                        </ul>
                        <!-- end of added code -->
                    </div>
                </div>
            
        

4. administrating user accounts, roles and permissions

Role based access control (RBAC) is a model in which roles are created for various job functions, and permissions to perform certain operations are then tied to roles. A user can be assigned one or multiple roles which restricts their system access to the permissions for which they have been authorized.

Webiness has integrated system for managing user accounts, roles and permissions and also provides interface for managing connections between them.

If you look again in previous code example, you see next code snippet:
            
                <?php
                if ($auth->hasPermission('admin') != true) {
                ?>
                    <li>
                        <a href="<?php echo WsUrl::link('wsauth','admin') ?>">
                            <?php echo WsLocalize::msg('User Accounts') ?>
                        </a>
                    </li>
                    <li>
                        <a href="<?php echo WsUrl::link('wsauth','userRoles') ?>">
                            <?php echo WsLocalize::msg('User Roles') ?>
                        </a>
                    </li>
                    <li>
                        <a href="<?php echo WsUrl::link('wsauth','rolePerms') ?>">
                            <?php echo WsLocalize::msg('Role Permissions') ?>
                        </a>
                    </li>
                <?php
                }
                ?>
            
        
In this code we introduce new public function hasPermission(permission_name). That function basically say: "if current user has named permission then do something". In our case it checks for administrators privilages and if it founds them then show links to administrators pages.

In our example, we create three roles (supervisor, operator and statistician) and two types of permissions (add item and see report). Users that have (that are in) operator role can add new report, users that have statistician role can see reports and users with supervisor role can do both. As you can see from screenshots (click to enlarge) administration UI is very simple and easy to use.

users, roles and permissions

user roles

role permissions

Now, lets go back to code in our basic tutorial and allow acces to report view only to users with 'supervisor' or 'statistician' roles.
            

                class ExpenseController extends WsController
                {
                    public $auth;

                    public function __construct()
                    {
                        parent::__construct();
                        // initialize user authentication
                        $this->auth = new WsAuth();
                    }


                    /*
                    .
                    .
                    more code here
                    .
                    .
                    */


                    public function expense_report()
                    {
                        // this has changed
                        if (!$this->auth->hasPermission('see report') == true) {
                            trigger_error('Access Forbiden', E_USER_ERROR);
                            return;
                        }

                        // view response to registrated users
                        $this->render('expense_report');
                    }
                }
            
        



Now you know how to use Webiness authentication and authorization system.