En las aplicaciones web donde tenemos zonas privadas que solo deben acceder los miembros registrados, debemos implementar mecanismos que permitan que los usuarios solo puedan ver una vez sean autenticados.
Filters
Los filters son herramientas de Rails que nos permiten interceptar llamadas a métodos y acciones, permitiéndonos añadir nuestros métodos ya sea antes, durante o después, de forma que podamos controlar el flujo de la aplicación como nos parezca para poder cumplir nuestras funcionalidades. En esta etapa vamos a utilizar el before filter para interceptar los llamados a nuestras acciones, de esta forma podemos verificar la sesión y saber si el usuario está logueado, si no entonces lo redirigimos a donde sea que hayamos dispuesto. Este método lo vamos a situar en nuestro controlador de aplicaciones ya que es la base y de esta forma estará disponible para toda la aplicación.
Veamos el código que tenemos para ello:
def authorize unless session[:user_id] flash[:notice] = "Please log in" redirect_to(:controller => "login", :action => "login") end end
Como vemos la lógica detrás de esto es bastante sencilla, utilizamos un condicional propio de Ruby que es el unless, esto nos permite condicionar que a menos que se cumpla la condición se ejecute el código del bloque. Entonces a menos que tengamos un id de un usuario en sesión vamos a redirigirlo y pedirle que se autentique en la aplicación.
Ahora en nuestro controlador del administrador vamos a filtrar y pedir a los usuarios que se autentiquen:
class AdminController < ApplicationController before_filter :authorize
Y en nuestro controlador de login también hacemos algo similar, solo que le añadiremos la excepción de la acción login que es la que nos interesa que pueda ser vista por cualquier usuario no autenticado:
class LoginController < ApplicationController before_filter :authorize, :except => :login
Si no estamos logueados debemos ver algo como esto al acceder a la página administrativa de la aplicación:
Ahora ya tenemos la forma de aplicar y filtrar que los usuarios no puedan ver los paneles administrativos si no están logueados, sin embargo tenemos una última inconsistencia, en la parte de eliminar usuarios debemos evitar que se borre el administrador general de la aplicación ya que si no lo hacemos, hay posibilidad que un usuario borre todos los usuarios y quedemos sin acceso a menos que modifiquemos directamente la base de datos y es algo inaceptable para nuestra aplicación. Para ello vamos nuevamente a crear un evento especial, en este caso será el before_destroy, lo que hace que antes de hacer la acción destroy ejecute un método.
Veamos el código:
before_destroy :dont_destroy_dave def dont_destroy_dave raise "Can't destroy dave" if self.name == 'dave' end
Luego en nuestra acción de borrado capturaremos el mensaje y lo mostraremos, veamos el código de la acción:
def delete_user id = params[:id] if id && user = User.find(id) begin user.destroy flash[:notice] = "User #{user.name} deleted" rescue flash[:notice] = "Can't delete that user" end end redirect_to(:action => :list_users) end
Con esto finalizamos nuestro tutorial de limitación de accesos en nuestra aplicación, es importante cubrir todas las posibilidades para evitar que los usuarios no autorizados puedan ver o modificar nuestra parte administrativa, esto para evitar dolores de cabeza futuros y problemas de seguridad que harán de nuestra aplicación insegura e inestable.