Authentication with the Sprig User Model

The Sprig Module is a object modeling system for Kohana, inspired by Django.

Sprig comes with a predefined model for working with users and using the main Sprig class it's pretty simple to provide user authentication.

Note that the following code sets/uses a simple cookie holding an ID which is not a secure way to authenticate a user as it can be easily falsified. The code below is to demonstrate the control flow and what authentication with Sprig would look like. Choose a more secure method for authentication.

Basic Process

  1. Download and install the Sprig Module
  2. Create a users table in your database
  3. Set up your template controller to redirect users who are not logged in
  4. Create and auth controller for loggin a user in and out

Creating the Database

Here is a database structure that can be used with the Sprig User Model.

  CREATE TABLE `users` (
    `id` int(10) unsigned NOT NULL auto_increment,
    `username` varchar(30) NOT NULL,
    `password` varchar(40) default NULL,
    PRIMARY KEY  (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

Set up your template controller to redirect users who are not logged in

The following template controller looks for a user cookie for every request. If a cookie is found it attempts to load the user record. If no cookie is found or the user record is not successfully loaded the controller redirects to the login form.

  abstract class Controller_Website extends Controller_Template {
  
      // Public variable for the user model
  	public $user;
      
      // Using TRUE means requests will require authentication by default
  	public $auth_required = TRUE;
  
  	public function __construct(Request $request)
  	{
  	    parent::__construct($request);
  
          // If a user id cookie is found attempt to load user
  	    if ($id = Cookie::get('user'))
  	    {
  	    	$user = Sprig::factory('user')
  	    		->values(array('id' => $id))
  	    		->load();
  
  	    	if ($user->loaded())
  	    	{
  	    		// User is logged in
  	    		$this->user = $user;
  	    	}
  	    }
              
          // If user is not logged in and login is required
  	    if ($this->auth_required AND ! $this->user)
  	    {
  	    	// Redirect to the login page
  	    	$request->redirect('auth/login');
  	    }
  	}
  }

The Auth Controller

The Auth controller below generates and validates a login form.

  class Controller_Auth extends Controller_Website {
  
      // This controller does not require authentication
  	public $auth_required = FALSE;
  
      // The login action    
  	public function action_login()
  	{
              // Set our View and bind with $user and $errors
  		$this->template->title   = 'Login';
  		$this->template->content = View::factory('auth/login')
  			->bind('user', $user)
  			->bind('errors', $errors);
  
  		// Load an empty user
  		$user = Sprig::factory('user');
  
              // Load rules defined in sprig model into validation factory    
  		$post = Validate::factory($_POST)
  			->rules('username', $user->field('username')->rules)
  			->rules('password', $user->field('password')->rules);
  
              // Validate the post    
  		if ($post->check())
  		{
  			// Load the user by username and password
  			$user->values($post->as_array())->load();
  
  			if ($user->loaded())
  			{
  				// Store the user id
  				Cookie::set('user', $user->id);
  
  				// Redirect to the home page
  				$this->request->redirect('');
  			}
  			else
  			{
  				$post->error('password', 'invalid');
  			}
  		}
  
  		$errors = $post->errors('auth/login');
  	}
  
  	public function action_logout()
  	{
  		$this->template->title = 'logout';
  		$this->template->content = View::factory('auth/logout');
  
  		if (isset($_POST['logout']))
  		{
  			// Delete the user cookie
  			Cookie::delete('user');
  
  			// Redirect to the home page
  			$this->request->redirect('');
  		}
  	}
  
  } // End Users
The Views

Here is the auth/login View

  <?php echo form::open(NULL, array('id' => 'login')) ?>
  
  <h1><?php echo __('Login') ?></h1>
  
  <?php include Kohana::find_file('views', 'errors') ?>
  
  <ol>
   <li><label><span><?php echo __('Username') ?></span> <?php echo form::input('username', $user->username) ?></label></li>
   <li><label><span><?php echo __('Password') ?></span> <?php echo form::password('password') ?></label></li>
  </ol>
  
  <?php echo form::button(NULL, 'Login', array('type' => 'submit')) ?>
  
  <?php echo form::close() ?>

Here is the auth/logout View

  <?php echo form::open(NULL, array('id' => 'logout')) ?>
  
  <h1 class="top">Log Out</h1>
  
  <p>Are you sure you want to log out?</p>
  
  <?php echo form::button('logout', 'Yes, please!', array('type' => 'submit')) ?>
  
  <?php echo form::close() ?>

And our errors View which is included into auth/login when there is an error.

  <?php if ( ! empty($errors)): ?>
  <ul class="errors">
  <?php foreach ($errors as $field => $error): ?>
   <li rel="<?php echo $field ?>"><?php echo ucfirst($error) ?></li>
  <?php endforeach ?>
  </ul>
  <?php endif ?>
authentication_with_sprig_user_model.txt · Last modified: 2009/11/10 21:57 by webthink