Login con sesiones en CodeIgniter

Soy un aprendiz en el framework CodeIgniter y estoy haciendo pequeños progresos, pero no sé si buenos o malos. Así que voy a publicar algunos progresos para que los más expertos que lean este artículo me puedan corregir o mejorar el código.

Mi objetivo es dotar a una pequeña aplicación realizada con CI de autenticación para que no se pueda acceder anónimamente. Para ello he creado un controlador ‘principal.php‘, un modelo ‘autenticacion_model.php‘ y una vista ‘form_login.php‘. La estructura queda así:

.
|– config
|– controllers
|   `– index.html
|   |– principal.php
|– models
|   |– autenticacion_model.php
|   `– index.html
`– views
|– autenticacion
|   `– form_login.php
`– index.html

El controlador principal.php tiene las siguientes funciones:

El constructor Principal carga los herlpers ‘url’ y ‘form’ y la library ‘form_validation’. Con esto podremos hacer uso de las funciones para crear urls y formularios y validaremos nuestro formulario.

La función index carga la vista ‘principal_view’ en caso de que exista la sesión de usuario, o, en caso contrario, redirige a la función login.

La función login comprueba que se ha enviado el formulario. En caso positivo, se pasan las variables ‘usuario’ y ‘contrasena’ a la función ‘verificaUsuario()’ que está en el modelo ‘Autenticacion_Model’ y que verificará que el usuario y contraseña existen en la base de datos y son correctos. Si son correctos se crean las variables de sesión ‘usuario_id’ y ‘login_ok’, y si no, genera un mensaje de error. Si el formulario no se envió, se carga la vista del formulario ‘form_login’ para que el usuario se autentique.

La función logout sólo elimina las variables de sesión anteriores y redirige al controlador ‘principal’.

<?php

class Principal extends Controller {

  function Principal()
  {
    parent::Controller();
    $this->load->helper(array('url', 'form'));
    $this->load->library('form_validation');
  }

  // Función index. Comprueba si existe la sesión de usuario
  function index()
  {
    // si no existe la sesión con la variable 'usuario_id'
    if (!$this->session->userdata('usuario_id')){
      // redirigimos a la función login
      redirect('principal/login', 'refresh');
    } else {
      // en caso contrario cargamos la vista principal
      $this->load->view('principal_view');
  }

  // Función login. Verifica el usuario/contraseña
  function login()
  {
    // si se ha enviado el formulario
    if ($this->input->post('usuario')){
      // recogemos las variables 'usuario' y 'contrasena'
      $usuario = $this->input->post('usuario');
      $contrasena = sha1($this->input->post('contrasena'));
      // cargamos el modelo para verificar el usuario/contraseña
      $this->load->model('Autenticacion_Model');
      // si el usuario y contraseña son correctos
      if ($this->Admin_Model->verificaUsuario($usuario, $contrasena)){
        // creamos un array con las variables de sesión 'usuario_id' y 'login_ok'
        $datasession = array(
          'usuario_id'  => '$usuario',
          'login_ok' => TRUE
        );
        // creamos la sesión con dichas variables
        $this->session->set_userdata($datasession);
        // y redirigimos al controlador principal
        redirect('principal', 'refresh');
      } else {
        // si el usuario y contraseña son incorrectos
        $this->session->set_flashdata('error', 'El usuario o contraseña son incorrectos.');
      }
    } else {
      // cargamos el formulario de login
      $this->load->view('autenticacion/form_login');
    }
  }

  // Función logout. Elimina las variables de sesión y redirige al controlador principal
  function logout()
  {
    // creamos un array con las variables de sesión en blanco
    $datasession = array('usuario_id' => '', 'logged_in' => '');
    // y eliminamos la sesión
    $this->session->unset_userdata($datasession);
    // redirigimos al controlador principal
    redirect('principal', 'refresh');
  }

}

El modelo Autenticacion_Model contiene la función ‘verificaUsuario’ que recibe como parámetros el usuario y contraseña y se conecta a la base de datos para comprobar que son correctos.

<?php

class Autenticacion_Model extends Model {

  function Autenticacion_Model()
  {
    parent::Model();
  }

  function verificaUsuario($usuario, $contrasena){
    // creamos la select
    // SELECT `usuario`, `contrasena`
    // WHERE `usuario` = $usuario AND
    // `contrasena` = $contrasena
    // FROM `ci_usuarios`
    // LIMIT 1
    $this->db->select('id, usuario');
    $this->db->where('usuario', $usuario);
    $this->db->where('contrasena', $contrasena);
    $this->db->limit(1);
    $query = $this->db->get('ci_usuarios');
    // si el resultado de la query es positivo
    if ($query->num_rows() > 0){
      // devolvemos TRUE
      return TRUE;
    // si el resultado de la query no es positivo
    } else {
      // devolvemos FALSE
      return FALSE;
    }
  }

}

Por último, la vista form_login sólo es un formulario solicitando usuario y contraseña:

<html>
<head>
<title>Login</title>
</head>
<body>

<?php echo form_open('principal/login') ?>
<?php echo form_label('Usuario: ', 'usuario') ?>
<?php echo form_input(array('name' => 'usuario', 'id' => 'nombre', 'size' => '50')) ?>
<?php echo form_label('Contraseña: ', 'contrasena') ?>
<?php echo form_input(array('name' => 'contrasena', 'id' => 'contrasena', 'size' => '50')) ?>
<?php echo form_submit('enviar', 'Enviar') ?>
<?php echo form_close() ?>

</body>
</html>

NOTA: Como veréis, cargué la library form_validation pero no la he usado. La razón es que aún no sé cómo funciona esa librería y espero aprenderlo en breve. En cuanto lo sepa modifico el código. Aún así, no es necesario validar el formulario para que nuestra autenticación funcione.